Ocean framework overview
Most of Port's native integrations, as well as the No-code Ocean custom integration, are built on Ocean, Port's open source integration framework.
This section explains the mechanisms Ocean provides to every integration built on it. It is intended for readers who want to understand what happens inside an integration, for example when tuning a self-hosted deployment or troubleshooting sync behavior.
What is Ocean?
Ocean is a Python framework made of two parts:
| Component | Description |
|---|---|
| Ocean core | A shared library (port-ocean on PyPI) that handles everything common to all integrations: communicating with Port, listening for resync requests, receiving live events, and executing actions. |
| Integrations | Individual applications (GitHub, Jira, AWS, and more) that use Ocean core and implement only the logic specific to one third-party tool, such as its API client and the data each kind returns. |
Because the core is shared, the mechanisms described in this section behave the same way across all Ocean integrations. Integration-specific behavior, such as which kinds and live events are supported, is documented on each integration's page.
How an Ocean integration runs
When an Ocean integration starts, it goes through the following steps:
- Load configuration - Ocean reads the integration configuration from environment variables and Port, and validates it against the integration's specification.
- Connect to Port - Ocean authenticates with Port using the integration's client credentials.
- Create default resources - If
initializePortResourcesistrue(default), Ocean creates the integration's default blueprints and mapping in Port. - Run startup hooks - The integration runs its own startup logic, for example registering webhooks in the third-party tool.
- Start the event listener - Ocean starts the configured event listener, which decides when to run a resync.
- Start background processors - If enabled, Ocean starts the live events processor and the actions processor.
From this point, the integration keeps running and reacts to three types of events:
| Event | Source | Handled by |
|---|---|---|
| Resync request | Port (configuration change, manual resync, or schedule) | Event listeners |
| Live event | The third-party tool (usually a webhook) | Live events processing |
| Action run | Port (a user or workflow runs an integration action) | Actions processing |
To check an integration's credentials and permissions without running a resync, use the connection probe. For network, endpoint, and HTTP client settings, see advanced configuration.
What an Ocean integration looks like
An Ocean integration is a Python application that registers handlers with Ocean core. The following main.py is adapted from the Jira integration, and shows how each mechanism in this section is wired:
from port_ocean.context.ocean import ocean
from port_ocean.core.ocean_types import ASYNC_GENERATOR_RESYNC_TYPE
# Resync: called for each kind in the mapping, yields raw data in batches.
@ocean.on_resync("project")
async def on_resync_projects(kind: str) -> ASYNC_GENERATOR_RESYNC_TYPE:
client = get_or_create_jira_client()
async for projects in client.get_paginated_projects():
yield projects
# Startup hook: runs once, for example to register webhooks in Jira.
@ocean.on_start()
async def on_start() -> None:
if ocean.event_listener_type == "ONCE":
return # A ONCE run exits after the resync, so it needs no webhooks
await setup_application()
# Connection probe: checks credentials and permissions without a resync.
@ocean.on_probe()
async def probe(context: ProbeContext) -> ProbeContext:
await JiraPermissionProbe(context).run()
return context
# Live events: processors registered for the /integration/webhook endpoint.
ocean.add_webhook_processor("/webhook", IssueWebhookProcessor)
ocean.add_webhook_processor("/webhook", ProjectWebhookProcessor)
# Actions: one executor per integration action.
ocean.register_action_executor(CreateIssueExecutor())
ocean.register_action_executor(AddCommentExecutor())
Everything else, such as polling Port for resync requests, queuing live events, claiming action runs, retries, and reporting status to Port, is handled by Ocean core.
What Ocean does and what Port does
During a resync, Ocean calls the integration's code for each kind in the mapping. The integration fetches the data from the third-party API in batches, and Ocean sends the raw data to Port.
Port then applies your mapping configuration to the raw data, ingests the resulting entities into the catalog, and runs reconciliation to delete stale entities. Ocean reports the resync's progress to Port throughout, so you can follow it on the integration's sync status page.
Live events follow the same split: Ocean receives the event and fetches the latest data from the third-party tool, and Port maps and ingests it.
Mapping, ingestion, and reconciliation are documented in the configure mapping and sync mechanisms sections.
Build your own Ocean integration
To build an integration from scratch using Ocean, see custom-coded Ocean integration.