### Install ASGI Server (uvicorn example) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/installation.rst Installs a supported ASGI server, using 'uvicorn' as an example, which is necessary for running FastAPI applications built with Extrawest OCPI. ```sh python -m pip install uvicorn ``` -------------------------------- ### Project File Structure Example Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/quickstart.rst An example of the expected file structure for the OCPI project, including the virtual environment, main application files, and configuration files. ```text my-ocpi-project/ venv/ main.py db.py crud.py auth.py .env ``` -------------------------------- ### Install Extrawest OCPI Library Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/installation.rst Installs the Extrawest OCPI library from PyPI using pip. This is the primary step to begin using the library for OCPI applications. ```sh python -m pip install extrawest-ocpi ``` -------------------------------- ### Install Motor for MongoDB Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/quickstart.rst This command installs the `motor` library, which is an asynchronous driver for MongoDB, necessary for database operations in the OCPI project. ```sh $ pip install motor ``` -------------------------------- ### GET /ocpi/cpo/2.1.1/locations/ Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/quickstart.rst Retrieves a list of locations managed by the CPO. Requires a valid authorization token. ```APIDOC ## GET /ocpi/cpo/2.1.1/locations/ ### Description Retrieves a list of locations managed by the Charge Point Operator (CPO). ### Method GET ### Endpoint /ocpi/cpo/2.1.1/locations/ ### Parameters #### Headers - **Authorization** (string) - Required - The authorization token for accessing the API (e.g., 'Token my_valid_token'). ### Request Example ```sh curl --request GET 'http://127.0.0.1:8000/ocpi/cpo/2.1.1/locations/' --header 'Authorization: Token my_valid_token' ``` ### Response #### Success Response (200) - **Example**: A JSON object containing a list of location data. #### Response Example (Response body structure would depend on the actual API implementation, typically including location details like ID, address, coordinates, and associated charging stations.) ### Further Information Consult the `/docs` or `/redoc/` endpoints on the running application for detailed schema and interactive API exploration (e.g., `http://127.0.0.1:8000/ocpi/docs/`). ``` -------------------------------- ### Install Extrawest OCPI Package Source: https://github.com/extrawest/extrawest_ocpi/blob/main/README.md Installs the extrawest-ocpi Python package using pip. This is the primary method for setting up the library in a project. ```bash pip install extrawest-ocpi ``` -------------------------------- ### Fetch OCPI Locations via cURL Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/quickstart.rst Demonstrates how to retrieve a list of locations from the OCPI API using a GET request with authorization. Ensure 'my_valid_token' is replaced with your actual authentication token. ```sh $ curl --request GET 'http://127.0.0.1:8000/ocpi/cpo/2.1.1/locations/' --header 'Authorization: Token my_valid_token' ``` -------------------------------- ### Get Limit Filter (Python) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/quickstart.rst Retrieves the limit value from the provided filters dictionary. Defaults to 0 if 'limit' is not found. ```python return filters.get("limit", 0) ``` -------------------------------- ### Install pre-commit hooks Source: https://github.com/extrawest/extrawest_ocpi/blob/main/CONTRIBUTING.md Installs the pre-commit framework for managing and executing pre-commit hooks. This helps automate code quality checks before commits. ```bash pre-commit install ``` -------------------------------- ### Install Python version with pyenv Source: https://github.com/extrawest/extrawest_ocpi/blob/main/CONTRIBUTING.md Installs a specific Python version (3.11.1) using pyenv. This command is run after pyenv has been installed and updated. ```bash pyenv install 3.11.1 ``` -------------------------------- ### Create Project Directory and Navigate Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/quickstart.rst Command-line instructions to create a new project directory and change into it. This is the initial step for setting up the OCPI project. ```sh $ mkdir my-ocpi-project $ cd my-ocpi-project/ ``` -------------------------------- ### Get Limit Filter from Dictionary (Python) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/db_interface_example.rst This method retrieves the 'limit' value from a filters dictionary. If 'limit' is not present, it defaults to 0. This is useful for pagination or restricting results. ```python @classmethod async def _get_limit_filter(cls, filters: dict) -> int: return filters.get("limit", 0) ``` -------------------------------- ### Get OCPI Versions (GET) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_2_1.rst Retrieves the available OCPI versions supported by the system. This endpoint does not require any specific parameters. ```http GET /versions ``` -------------------------------- ### Run FastAPI Application (Shell) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/quickstart.rst Command to run the FastAPI application using uvicorn, enabling live reloading for development. ```sh uvicorn main:app --reload ``` -------------------------------- ### Run pytest tests Source: https://github.com/extrawest/extrawest_ocpi/blob/main/CONTRIBUTING.md Executes all tests in the project using the pytest framework. This command should be run after installing dependencies and activating the virtual environment. ```bash pytest ``` -------------------------------- ### Initialize FastAPI Application (Python) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/quickstart.rst Sets up the FastAPI application instance using the `get_application` function from the `py_ocpi` library. It configures version numbers, roles, modules, authenticator, and CRUD implementation. ```python from py_ocpi import get_application from py_ocpi.core.enums import RoleEnum, ModuleID from py_ocpi.modules.versions.enums import VersionNumber from .auth import ClientAuthenticator from .crud import AppCrud app = get_application( version_numbers=[VersionNumber.v_2_1_1], roles=[RoleEnum.cpo], modules=[ModuleID.locations], authenticator=ClientAuthenticator, crud=AppCrud, ) ``` -------------------------------- ### Initialize pipenv environment Source: https://github.com/extrawest/extrawest_ocpi/blob/main/CONTRIBUTING.md Initializes a new pipenv virtual environment for the project, specifying Python 3.11.1. This command creates a Pipfile and installs base dependencies. ```bash pipenv --python 3.11.1 ``` -------------------------------- ### Get Offset Filter (Python) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/quickstart.rst Retrieves the offset value from the provided filters dictionary. Defaults to 0 if 'offset' is not found. ```python return filters.get("offset", 0) ``` -------------------------------- ### Get OCPI Version Details (GET) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_2_1.rst Retrieves detailed information about a specific OCPI version. The version number is part of the URL path. ```http GET /2.2.1/details ``` -------------------------------- ### Get Versions (General) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_1_1.rst Retrieves the available OCPI versions supported by the system. This is a general endpoint applicable to all roles. ```python from py_ocpi.modules.versions.main import get_versions ``` -------------------------------- ### Get Date To Query from Dictionary (Python) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/db_interface_example.rst This method constructs a MongoDB-style query to filter documents with a 'last_updated' field less than or equal to a specified date. It takes a 'date_to' from the filters dictionary. ```python @classmethod async def _get_date_to_query(cls, filters: dict) -> int: query = {} date_to = filters.get("date_to") if date_to: query.setdefault("last_updated", {}).update( {"$lte": date_to.isoformat()} ) return query ``` -------------------------------- ### Get Date To Query Filter (Python) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/quickstart.rst Constructs a query part for a 'date_from' filter. It sets the '$gte' condition on the 'last_updated' field if 'date_from' is present in the filters. ```python query = {} date_from = filters.get("date_from") if date_from: query.setdefault("last_updated", {}).update({"$gte": date_from.isoformat()}) return query ``` -------------------------------- ### Create and Activate Virtual Environment Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/quickstart.rst Command to create a virtual environment named 'venv'. It's crucial to use Python version 3.10 or higher for this project. ```sh $ virualenv venv ``` -------------------------------- ### Update pyenv Source: https://github.com/extrawest/extrawest_ocpi/blob/main/CONTRIBUTING.md Updates the pyenv Python version manager to the latest version. Ensure pyenv is installed before running this command. ```bash pyenv update ``` -------------------------------- ### Get Date From Query Filter (Python) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/quickstart.rst Constructs a query part for a 'date_to' filter. It sets the '$lte' condition on the 'last_updated' field if 'date_to' is present in the filters. ```python query = {} date_to = filters.get("date_to") if date_to: query.setdefault("last_updated", {}).update({"$lte": date_to.isoformat()}) return query ``` -------------------------------- ### Get Tariff (GET) - EMSP v2.1.1 Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_1_1.rst Fetches tariff information using a GET request in the EMPS module for version 2.1.1. This endpoint provides details about charging tariffs. ```python py_ocpi.modules.tariffs.v_2_1_1.api.emsp.get_tariff ``` -------------------------------- ### ClientAuthenticator Token Retrieval (Python) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/quickstart.rst Provides methods to retrieve valid authorization tokens for different roles (CPO and Stakeholder). These tokens are used for authentication. ```python from typing import List from py_ocpi.core.authentication.authenticator import Authenticator class ClientAuthenticator(Authenticator): @classmethod async def get_valid_token_c(cls) -> List[str]: """Return a list of valid tokens c.""" return ["my_valid_token_c"] @classmethod async def get_valid_token_a(cls) -> List[str]: """Return a list of valid tokens a.""" return ["my_valid_token_a"] ``` -------------------------------- ### Get Date From Query from Dictionary (Python) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/db_interface_example.rst This method constructs a MongoDB-style query to filter documents with a 'last_updated' field greater than or equal to a specified date. It takes a 'date_from' from the filters dictionary. ```python @classmethod async def _get_date_from_query(cls, filters: dict) -> int: query = {} date_from = filters.get("date_from") if date_from: query.setdefault("last_updated", {}).update( {"$gte": date_from.isoformat()} ) return query ``` -------------------------------- ### MongoDB Database Interface with Motor Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/quickstart.rst Python code defining a `DbInterface` class for interacting with a MongoDB database using the `motor` library. It includes methods for retrieving single objects, paginated lists, and counting documents, specifically for the 'locations' module. ```python from motor import motor_asyncio from py_ocpi.core.config import logger from py_ocpi.core.enums import ModuleID db_url = f"mongodb+srv://mongo-username:mongo-password@mongo-host" client = motor_asyncio.AsyncIOMotorClient(db_url) db = client.ocpi_database class DbInterface: """Mongo db operations interface class.""" MODULE_MAP = { ModuleID.locations: "locations_table", } @classmethod async def get(cls, module, id, *args, **kwargs) -> dict | None: """Return single object from collection.""" logger.info("GET obj from `%s` module with id - `%s`" % (module, id)) collection = cls.MODULE_MAP[module] match module: case ModuleID.locations: query = {"id": id} case _: raise NotImplementedError return await db[collection].find_one(query) @classmethod async def get_all(cls, module, filters, *args, **kwargs) -> tuple[list[dict], int, bool]: """GET paginated list of objects result from collection.""" data_list = await cls.list(module, filters, *args, **kwargs) total = await cls.count(module, filters, *args, **kwargs) is_last_page = await cls.is_last_page( module, filters, total, *args, **kwargs ) return data_list, total, is_last_page @classmethod async def list(cls, module, filters, *args, **kwargs) -> list[dict]: """GET paginated list of objects result from collection.""" collection = cls.MODULE_MAP[module] offset = await cls._get_offset_filter(filters) limit = await cls._get_limit_filter(filters) query = await cls._get_date_from_query(filters) query |= await cls._get_date_to_query(filters) return await db[collection].find(query).sort("_id").skip(offset).limit(limit).to_list(None) @classmethod async def count(cls, module, filters, *args, **kwargs) -> int: ``` -------------------------------- ### Python CRUD Operations for OCPI Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/crud_example.rst Implements core Create, Read, Update, Delete (CRUD) operations for OCPI modules. It interacts with a `DbInterface` for data persistence and includes specific handling for credentials and registration, such as managing integration data and tokens. ```python import copy from typing import Any, Tuple from uuid import uuid4 from py_ocpi.core.crud import Crud from py_ocpi.core.enums import ModuleID, RoleEnum, Action from .db_interface import DbInterface class CrudExample(Crud): @classmethod async def get( cls, module: ModuleID, role: RoleEnum, id, *args, **kwargs ) -> Any: return await DbInterface.get(module, id, *args, **kwargs) @classmethod async def list( cls, module: ModuleID, role: RoleEnum, filters: dict, *args, **kwargs ) -> Tuple[list, int, bool]: data_list, total, is_last_page = await DbInterface.get_all( module, filters, *args, **kwargs ) return data_list, total, is_last_page @classmethod async def create( cls, module: ModuleID, role: RoleEnum, data: dict, *args, **kwargs ) -> Any: if module == ModuleID.credentials_and_registration: # It's advised to save somewhere in separate table token B sent by client: integration_data = copy.deepcopy(data["credentials"]) integration_data["endpoints"] = data.pop("endpoints") integration_data["credentials_id"] = auth_token await DbInterface.create( "integration", integration_data, *args, **kwargs ) # It's advised to re-create token A after it was used for register purpose # Implement your own logic here token_a = uuid4() return await DbInterface.create(module, data, *args, **kwargs) @classmethod async def update( cls, module: ModuleID, role: RoleEnum, data: dict, id, *args, **kwargs ) -> Any: match module: case ModuleID.credentials_and_registration: # re-create client credentials await DbInterface.update( "integration", data, id, *args, **kwargs ) # Generate new token_c instead the one client used new_token_с = uuid4() data = {"token": new_token_с} return await DbInterface.update(module, data, id, *args, **kwargs) @classmethod async def delete( cls, module: ModuleID, role: RoleEnum, id, *args, **kwargs ): if module.credentials_and_registration: # Make sure to delete corresponding token_b given you by client await DbInterface.delete("integration", id, *args, **kwargs) await DbInterface.delete(module, id, *args, **kwargs) @classmethod async def do( cls, module: ModuleID, role: RoleEnum, action: Action, *args, data: dict = None, **kwargs, ) -> Any: """CRUD DO.""" auth_token = kwargs["auth_token"] match action: case Action.get_client_token: token_b = await DbInterface.get( "integration", auth_token, *args, **kwargs ) return token_b["token"] case Action.authorize_token: # TODO: implement your token auth business logic here return {} case Action.send_command: # TODO: implement your send command to Charge Point business logic here pass case Action.send_get_chargingprofile: # TODO: implement your set charging profile business logic here pass case Action.send_delete_chargingprofile: # TODO: implement your delete charging profile business logic here pass case Action.send_update_charging_profile: # TODO: implement your update charging profile business logic here pass ``` -------------------------------- ### Get Tokens (EMSP v2.2.1) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_2_1.rst Retrieves a list of tokens managed by the EMSP through the OCPI 2.2.1 API. ```http GET emsp/2.2.1/tokens/ ``` -------------------------------- ### AppCrud Class Implementation (Python) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/quickstart.rst Implements CRUD operations for the application, extending the base Crud class. It handles retrieving single objects and lists of objects from the database. ```python from typing import Any, Tuple from py_ocpi.core.config import logger from py_ocpi.core.crud import Crud from py_ocpi.core.enums import ModuleID, RoleEnum, Action from .db import DbInterface class AppCrud(Crud): """Class contains crud business logic.""" @classmethod async def get( cls, module: ModuleID, role: RoleEnum, id, *args, **kwargs ) -> dict | None: """Return single obj from db.""" logger.info( 'Get single obj -> module - `%s`, role - `%s`, version - `%s`' % (module, role, kwargs.get("version", "")) ) return await DbInterface.get(module, id, *args, **kwargs) @classmethod async def list( cls, module: ModuleID, role: RoleEnum, filters: dict, *args, **kwargs ) -> tuple[list[dict], int, bool]: """Return list of obj from db.""" logger.info( 'Get list of objs -> module - `%s`, role - `%s`, version - `%s`' % (module, role, kwargs.get("version", "")) ) data_list, total, is_last_page = await DbInterface.get_all( module, filters, *args, **kwargs ) return data_list, total, is_last_page ``` -------------------------------- ### GET /emsp/2.2.1/tokens/ Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_2_1.rst Retrieves a list of tokens. This endpoint allows fetching all registered tokens, potentially with filtering options. ```APIDOC ## GET /emsp/2.2.1/tokens/ ### Description Retrieves a list of tokens. This endpoint allows fetching all registered tokens, potentially with filtering options. ### Method GET ### Endpoint emsp/2.2.1/tokens/ ### Parameters #### Query Parameters - **limit** (integer) - Optional - The maximum number of tokens to return. - **offset** (integer) - Optional - The number of tokens to skip before returning results. ### Response #### Success Response (200) - **tokens** (array) - A list of token objects. #### Response Example ```json { "tokens": [ { "uid": "TOKEN123", "type": "RFID", "authorization_info": { "authorization_status": "ACCEPTED" } } ] } ``` ``` -------------------------------- ### Get Version Details (OCPI 2.1.1) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_1_1.rst Fetches detailed information about the OCPI version 2.1.1. This endpoint provides specific details for a particular version. ```python from py_ocpi.modules.versions.v_2_1_1.api.main import get_version_details ``` -------------------------------- ### Python DB Interface for OCPI Modules Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/db_interface_example.rst This Python class, `DbInterface`, provides asynchronous methods to interact with a MongoDB database for various OCPI modules. It maps module IDs to collection names and handles CRUD operations, including specific query logic for different modules like tokens and integrations. It relies on the `motor` library for async MongoDB access. ```python from motor import motor_asyncio from py_ocpi.core.enums import ModuleID client = motor_asyncio.AsyncIOMotorClient("db_url") db = client.ocpi_database class DbInterface: MODULE_MAP = { ModuleID.credentials_and_registration: "credentials_table", ModuleID.locations: "locations_table", ModuleID.cdrs: "cdrs_table", ModuleID.tokens: "tokens_table", ModuleID.tariffs: "tariffs_table", ModuleID.sessions: "sessions_table", ModuleID.commands: "commands_table", "integration": "integration_table", ModuleID.hub_client_info: "hubclientinfo_table", ModuleID.charging_profile: "chargingprofile_table", } @classmethod async def get(cls, module, id, *args, **kwargs) -> dict | None: collection = cls.MODULE_MAP[module] match module: case ModuleID.commands: # TODO: implement query using your identification for commands command_data = kwargs["comand_data"] query = {} case ModuleID.tokens: query = {"uid": id} case "integration": query = {"credentials_id": id} case _: query = {"id": id} return await db[collection].find_one(query) @classmethod async def get_all(cls, module, filters, *args, **kwargs) -> tuple[list[dict], int, bool]: data_list = await cls.list(module, filters, *args, **kwargs) total = await cls.count(module, filters, *args, **kwargs) is_last_page = await cls.is_last_page( module, filters, total, *args, **kwargs ) return data_list, total, is_last_page @classmethod async def list(cls, module, filters, *args, **kwargs) -> list[dict]: collection = cls.MODULE_MAP[module] offset = await cls._get_offset_filter(filters) limit = await cls._get_limit_filter(filters) query = await cls._get_date_from_query(filters) query |= await cls._get_date_to_query(filters) return ( await db[collection] .find( query, ) .sort("_id") .skip(offset) .limit(limit) .to_list(None) ) @classmethod async def create(cls, module, data, *args, **kwargs) -> dict: collection = cls.MODULE_MAP[module] return await db[collection].insert_one(data) @classmethod async def update(cls, module, data, id, *args, **kwargs) -> dict: collection = cls.MODULE_MAP[module] match module: case ModuleID.tokens: token_type = kwargs.get("token_type") query = {"uid": id} if token_type: query |= {"token_type": token_type} case "integration": query = {"credentials_id": id} case ModuleID.credentials_and_registration: query = {"token": id} case _: query = {"id": id} return await db[collection].update_one(query, {"$set": data}) @classmethod async def delete(cls, module, id, *args, **kwargs) -> None: collection = cls.MODULE_MAP[module] if module == ModuleID.credentials_and_registration: query = {"token": id} else: query = {"id": id} await db[collection].delete_one(query) @classmethod async def count(cls, module, filters, *args, **kwargs) -> int: collection = cls.MODULE_MAP[module] query = await cls._get_date_from_query(filters) query |= await cls._get_date_to_query(filters) total = db[collection].count_documents(query) return total @classmethod async def is_last_page( cls, module, filters, total, *args, **kwargs ) -> bool: offset = await cls._get_offset_filter(filters) limit = await cls._get_limit_filter(filters) return offset + limit >= total if limit else True @classmethod async def _get_offset_filter(cls, filters: dict) -> int: return filters.get("offset", 0) ``` -------------------------------- ### Manage Credentials (eMSP Role) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_1_1.rst Provides endpoints for eMSP role to manage credentials. This includes GET, POST, PUT, and DELETE operations for credentials. ```python from py_ocpi.modules.credentials.v_2_1_1.api.emsp import get_credentials, post_credentials, update_credentials, remove_credentials ``` -------------------------------- ### Manage Credentials (CPO Role) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_1_1.rst Provides endpoints for CPO role to manage credentials. This includes GET, POST, PUT, and DELETE operations for credentials. ```python from py_ocpi.modules.credentials.v_2_1_1.api.cpo import get_credentials, post_credentials, update_credentials, remove_credentials ``` -------------------------------- ### Manage CDRs (eMSP Role) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_1_1.rst Provides endpoints for eMSP role to manage Charge Detail Records (CDRs). This includes getting a specific CDR and adding a new CDR. ```python from py_ocpi.modules.cdrs.v_2_1_1.api.emsp import get_cdr, add_cdr ``` -------------------------------- ### Get Tariffs (CPO Role) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_1_1.rst Retrieves tariff information for the CPO role. This endpoint allows fetching tariff data. ```python from py_ocpi.modules.tariffs.v_2_1_1.api.cpo import get_tariffs ``` -------------------------------- ### Count Documents in Collection (Python) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/quickstart.rst Counts the number of documents in a specified collection based on provided filters. It utilizes helper methods to construct the query from date filters. ```python collection = cls.MODULE_MAP[module] query = await cls._get_date_from_query(filters) query |= await cls._get_date_to_query(filters) total = db[collection].count_documents(query) return total ``` -------------------------------- ### Manage Tokens (CPO Role) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_1_1.rst Provides endpoints for CPO role to manage tokens. This includes GET, PUT (add/update), and PATCH (partial update) operations for tokens. ```python from py_ocpi.modules.tokens.v_2_1_1.api.cpo import get_token, add_or_update_token, partial_update_token ``` -------------------------------- ### CPO Locations Management (GET) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_2_1.rst Endpoints for retrieving location-related data as a Charge Point Operator (CPO). Supports fetching all locations, a specific location, EVSE details, or connector details. ```http GET /cpo/2.2.1/locations/ ``` ```http GET /cpo/2.2.1/locations/{location_id} ``` ```http GET /cpo/2.2.1/locations/{location_id}/{evse_uid} ``` ```http GET /cpo/2.2.1/locations/{location_id}/{evse_uid}/{connector_id} ``` -------------------------------- ### Check if Last Page (Python) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/quickstart.rst Determines if the current paginated result set is the last page. It calculates this based on the offset, limit, and the total number of items. ```python offset = await cls._get_offset_filter(filters) limit = await cls._get_limit_filter(filters) return offset + limit >= total if limit else True ``` -------------------------------- ### Initialize Extrawest OCPI with Push Support (Python) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/push.rst Demonstrates how to initialize the Extrawest OCPI application with both HTTP and WebSocket push capabilities enabled. It showcases the necessary imports and configuration parameters for setting up push functionality. ```python from py_ocpi import get_application from py_ocpi.core.enums import RoleEnum, ModuleID from py_ocpi.modules.versions.enums import VersionNumber from auth import ClientAuthenticator from crud import Crud app = get_application( version_numbers=[VersionNumber.v_2_1_1], roles=[RoleEnum.cpo], modules=[ModuleID.locations], authenticator=ClientAuthenticator, crud=Crud, http_push=True, websocket_push=True, ) ``` -------------------------------- ### Clone extrawest_ocpi repository Source: https://github.com/extrawest/extrawest_ocpi/blob/main/CONTRIBUTING.md Clones the extrawest_ocpi project from its GitHub repository. This is the first step in setting up the project locally. ```bash git clone https://github.com/extrawest/extrawest_ocpi.git ``` -------------------------------- ### Change directory to project Source: https://github.com/extrawest/extrawest_ocpi/blob/main/CONTRIBUTING.md Navigates into the cloned extrawest_ocpi project directory. This command must be run after cloning the repository. ```bash cd extrawest_ocpi ``` -------------------------------- ### Get Tokens (GET) - EMSP v2.1.1 Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_1_1.rst Retrieves a list of tokens via a GET request in the EMPS module for version 2.1.1. This function is essential for token management and access control. ```python py_ocpi.modules.tokens.v_2_1_1.api.emsp.get_tokens ``` -------------------------------- ### CPO Tariffs Retrieval (GET) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_2_1.rst Endpoint for retrieving tariff information as a Charge Point Operator (CPO). ```http GET /cpo/2.2.1/tariffs/ ``` -------------------------------- ### Activate pipenv virtual environment Source: https://github.com/extrawest/extrawest_ocpi/blob/main/CONTRIBUTING.md Activates the pipenv virtual environment, allowing you to run project-specific commands and scripts within an isolated Python environment. ```bash pipenv shell ``` -------------------------------- ### CPO Sessions Retrieval (GET) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_2_1.rst Endpoint for retrieving charging session data as a Charge Point Operator (CPO). ```http GET /cpo/2.2.1/sessions/ ``` -------------------------------- ### CPO CDRs Retrieval (GET) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_2_1.rst Endpoint for retrieving Charge Detail Records (CDRs) as a Charge Point Operator (CPO). ```http GET /cpo/2.2.1/cdrs/ ``` -------------------------------- ### GET /emsp/2.1.1/tokens/ Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_1_1.rst Retrieves a list of tokens associated with the user. This endpoint allows fetching token information. ```APIDOC ## GET /emsp/2.1.1/tokens/ ### Description Retrieves a list of tokens associated with the user. This endpoint allows fetching token information. ### Method GET ### Endpoint /emsp/2.1.1/tokens/ ### Parameters #### Query Parameters - **limit** (integer) - Optional - Maximum number of tokens to return. - **offset** (integer) - Optional - The offset for pagination. - **date_from** (string) - Optional - Filter tokens from this date and time (ISO 8601 format). - **date_to** (string) - Optional - Filter tokens up to this date and time (ISO 8601 format). - **status** (string) - Optional - Filter tokens by status (e.g., "ACTIVE", "INACTIVE"). ### Response #### Success Response (200) - **tokens** (array) - A list of token objects. - **uid** (string) - Unique identifier for the token. - **type** (string) - Type of the token (e.g., "RFID", "APP_USER_ID"). - **authentication_id** (string) - The identifier used for authentication. - **language** (string) - Preferred language for the token holder. - **token_group_id** (string) - Identifier for the group the token belongs to. - **authorized_value** (string) - The maximum amount that can be charged with this token. - **visual_number** (string) - A human-readable number on the token. - **uuid** (string) - Unique identifier for the token record. #### Response Example ```json { "tokens": [ { "uid": "ABCDEF123456", "type": "RFID", "authentication_id": "AUTHID123", "language": "en", "token_group_id": "GROUP1", "authorized_value": "50.00", "visual_number": "123456789", "uuid": "7a9f8b3d-1b2a-4c5d-8e7f-9a0b1c2d3e4f" } ] } ``` ``` -------------------------------- ### Tariffs Module Schemas (v2.1.1 and general) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_1_1.rst Presents the schemas for the Tariffs module, including version 2.1.1 and general schemas. These define the structure for tariff data. ```python py_ocpi.modules.tariffs.v_2_1_1.schemas ``` ```python py_ocpi.modules.tariffs.schemas ``` -------------------------------- ### Credentials Module Schemas (v2.2.1) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_2_1.rst Provides schema definitions for the Credentials module in OCPI v2.2.1. ```python from py_ocpi.modules.credentials.v_2_2_1.schemas import * from py_ocpi.modules.credentials.v_2_2_1.schemas import * from py_ocpi.modules.credentials.v_2_2_1.schemas import * from py_ocpi.modules.credentials.v_2_2_1.schemas import * from py_ocpi.modules.credentials.v_2_2_1.schemas import * from py_ocpi.modules.credentials.v_2_2_1.schemas import * from py_ocpi.modules.credentials.v_2_2_1.schemas import * from py_ocpi.modules.credentials.v_2_2_1.schemas import * ``` -------------------------------- ### WebSocket Push Endpoint Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/tutorial/push.rst When `websocket_push` is enabled, a new WebSocket endpoint is available for real-time updates. Authentication is handled via a `token` query parameter. ```APIDOC ## WS /push/ws/{version} ### Description WebSocket endpoint for receiving real-time object updates. ### Method WS (WebSocket) ### Endpoint /push/ws/{version} ### Parameters #### Path Parameters - **version** (string) - Required - The OCPI version number (e.g., 2.1.1). #### Query Parameters - **token** (string) - Required - The authentication token for the WebSocket connection. ### Connection Example `ws://127.0.0.1:8000/push/ws/2.1.1?token=` ### Notes - Uses the `token` query parameter for authentication. ``` -------------------------------- ### GET /emsp/2.2.1/clientinfo/{country_code}/{party_id} Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_2_1.rst Retrieves client information for a specific party in a given country. This endpoint is used to fetch details about connected partners or service providers. ```APIDOC ## GET /emsp/2.2.1/clientinfo/{country_code}/{party_id} ### Description Retrieves client information for a specific party in a given country. This endpoint is used to fetch details about connected partners or service providers. ### Method GET ### Endpoint emsp/2.2.1/clientinfo/{country_code}/{party_id} ### Parameters #### Path Parameters - **country_code** (string) - Required - The country code. - **party_id** (string) - Required - The party ID. ### Response #### Success Response (200) - **hub_client_info** (object) - Information about the hub client. #### Response Example ```json { "hub_client_info": { "country_code": "NL", "party_id": "CPO1", "roles": ["CPO", "EMSP"] } } ``` ``` -------------------------------- ### Commands Module Schemas (v2.2.1) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_2_1.rst Provides schema definitions for the Commands module in OCPI v2.2.1. ```python from py_ocpi.modules.commands.v_2_2_1.schemas import * from py_ocpi.modules.commands.v_2_2_1.schemas import * from py_ocpi.modules.commands.v_2_2_1.schemas import * from py_ocpi.modules.commands.v_2_2_1.schemas import * from py_ocpi.modules.commands.v_2_2_1.schemas import * from py_ocpi.modules.commands.v_2_2_1.schemas import * from py_ocpi.modules.commands.v_2_2_1.schemas import * from py_ocpi.modules.commands.v_2_2_1.schemas import * ``` -------------------------------- ### GET /emsp/2.2.1/tariffs/{country_code}/{party_id}/{tariff_id} Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_2_1.rst Retrieves details of a specific tariff by its unique identifier. This endpoint allows fetching tariff information for a given location and party. ```APIDOC ## GET /emsp/2.2.1/tariffs/{country_code}/{party_id}/{tariff_id} ### Description Retrieves details of a specific tariff by its unique identifier. This endpoint allows fetching tariff information for a given location and party. ### Method GET ### Endpoint emsp/2.2.1/tariffs/{country_code}/{party_id}/{tariff_id} ### Parameters #### Path Parameters - **country_code** (string) - Required - The country code of the location. - **party_id** (string) - Required - The party ID associated with the tariff. - **tariff_id** (string) - Required - The unique identifier for the tariff. ### Response #### Success Response (200) - **tariff** (object) - The tariff object. #### Response Example ```json { "tariff": { "id": "TARIFF123", "currency": "EUR", "elements": [ { "price_component": { "type": "ENERGY_PRICE", "price": 0.25 } } ] } } ``` ``` -------------------------------- ### GET /emsp/2.2.1/sessions/{country_code}/{party_id}/{session_id} Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_2_1.rst Retrieves details of a specific charging session by its unique identifier. This endpoint allows fetching real-time or historical session data. ```APIDOC ## GET /emsp/2.2.1/sessions/{country_code}/{party_id}/{session_id} ### Description Retrieves details of a specific charging session by its unique identifier. This endpoint allows fetching real-time or historical session data. ### Method GET ### Endpoint emsp/2.2.1/sessions/{country_code}/{party_id}/{session_id} ### Parameters #### Path Parameters - **country_code** (string) - Required - The country code of the location. - **party_id** (string) - Required - The party ID associated with the session. - **session_id** (string) - Required - The unique identifier for the session. ### Response #### Success Response (200) - **session** (object) - The charging session object. #### Response Example ```json { "session": { "id": "SESS123", "start_date_time": "2023-01-01T10:00:00Z", "status": "ACTIVE", "authorization_id": "AUTH456" } } ``` ``` -------------------------------- ### GET /emsp/2.2.1/cdrs/{cdr_id} Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_2_1.rst Retrieves a specific Charge Detail Record (CDR) by its unique identifier. This endpoint is used to fetch detailed information about a past charging session. ```APIDOC ## GET /emsp/2.2.1/cdrs/{cdr_id} ### Description Retrieves a specific Charge Detail Record (CDR) by its unique identifier. This endpoint is used to fetch detailed information about a past charging session. ### Method GET ### Endpoint emsp/2.2.1/cdrs/{cdr_id} ### Parameters #### Path Parameters - **cdr_id** (string) - Required - The unique identifier for the CDR. ### Response #### Success Response (200) - **cdr** (object) - The Charge Detail Record object. #### Response Example ```json { "cdr": { "id": "CDR123", "start_date_time": "2023-01-01T10:00:00Z", "end_date_time": "2023-01-01T11:00:00Z", "authorization_id": "AUTH456" } } ``` ``` -------------------------------- ### Get CDR by ID (EMSP v2.2.1) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_2_1.rst Retrieves a specific Charging Data Record (CDR) using its unique identifier via the OCPI 2.2.1 EMSP API. ```http GET emsp/2.2.1/cdrs/{cdr_id} ``` -------------------------------- ### POST /emsp/2.1.1/commands/{uid} Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_1_1.rst Sends a command to a charge point and receives the result. This endpoint is for command execution. ```APIDOC ## POST /emsp/2.1.1/commands/{uid} ### Description Sends a command to a charge point and receives the result. This endpoint is for command execution. ### Method POST ### Endpoint /emsp/2.1.1/commands/{uid} ### Parameters #### Path Parameters - **uid** (string) - Required - The unique identifier for the command. #### Request Body - **command** (string) - Required - The type of command to send (e.g., "RESERVE_NOW", "START_SESSION", "STOP_SESSION"). - **action** (string) - Required - The action associated with the command. - **location_id** (string) - Required - The identifier of the location where the command should be executed. - **connector_id** (string) - Required - The identifier of the connector for the command. - **command_data** (object) - Optional - Data specific to the command. - **token** (object) - Token information for authorization. - **start_session_info** (object) - Information for starting a session. - **stop_session_info** (object) - Information for stopping a session. ### Request Example ```json { "command": "START_SESSION", "action": "StartSession", "location_id": "LOC1", "connector_id": "C1", "command_data": { "token": { "uid": "ABCDEF123456", "type": "RFID" } } } ``` ### Response #### Success Response (200) - **result** (object) - The result of the command execution. - **status** (string) - The status of the command execution (e.g., "ACCEPTED", "REJECTED", "FR...'} #### Response Example ```json { "result": { "status": "ACCEPTED", "message": "Command accepted and queued." } } ``` ``` -------------------------------- ### eMSP Locations Management (GET) Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_2_1.rst Endpoints for retrieving location-related data as an eMobility Service Provider (eMSP). Supports fetching specific location, EVSE, or connector details. ```http GET /emsp/2.2.1/locations/{country_code}/{party_id}/{location_id} ``` ```http GET /emsp/2.2.1/locations/{country_code}/{party_id}/{location_id}/{evse_uid} ``` ```http GET /emsp/2.2.1/locations/{country_code}/{party_id}/{location_id}/{evse_uid}/{connector_id} ``` -------------------------------- ### Commands Module Schemas Source: https://github.com/extrawest/extrawest_ocpi/blob/main/docs/source/api/v_2_1_1.rst Provides access to the schemas for the Commands module in version 2.1.1. These schemas define the structure for command-related data. ```python py_ocpi.modules.commands.v_2_1_1.schemas ```