{"id":42345,"date":"2026-02-23T08:24:00","date_gmt":"2026-02-23T07:24:00","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/?p=42345"},"modified":"2026-06-28T05:59:40","modified_gmt":"2026-06-28T03:59:40","slug":"production-ready-goldengate-rest-client-in-python","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/","title":{"rendered":"Production-ready GoldenGate REST client in Python"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong><em>Updated in June 2026<\/em><\/strong>, based on the latest version of the client.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this blog, I provide GoldenGate administrators with a <strong>fully working, production-ready Python client<\/strong> to efficiently handle <strong>GoldenGate REST API<\/strong> calls. From extract creation to user management, it has never been easier to manage and monitor your GoldenGate deployments !<\/p>\n\n\n\n<div class=\"wp-block-yoast-seo-table-of-contents yoast-table-of-contents\"><h2>Table of contents<\/h2><ul><li><a href=\"#h-basic-oggrestapi-python-class\" data-level=\"2\">Basic OGGRestAPI Python class<\/a><\/li><li><a href=\"#h-example-of-a-rest-api-method-in-the-client\" data-level=\"2\">Example of a REST API method in the client<\/a><\/li><li><a href=\"#h-where-to-find-the-code\" data-level=\"2\">Where to find the code ?<\/a><\/li><li><a href=\"#h-how-to-use-the-client\" data-level=\"2\">How to use the client ?<\/a><\/li><li><a href=\"#h-call-examples\" data-level=\"2\">Call examples<\/a><\/li><li><a href=\"#h-method-naming-explanation\" data-level=\"2\">Method naming explanation<\/a><\/li><\/ul><\/div>\n\n\n\n<h2 id=\"h-basic-oggrestapi-python-class\" class=\"wp-block-heading\">Basic <code>OGGRestAPI<\/code> Python class<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In a previous <a href=\"https:\/\/www.dbi-services.com\/blog\/goldengate-rest-api-basics-with-python\/\" target=\"_blank\" rel=\"noreferrer noopener\">blog post<\/a>, I presented a basic Python script for making calls to the GoldenGate REST API. I also provided an <code>OGGRestAPI<\/code> Python class to handle the connections and API responses. This class serves as the base structure of the client.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import getpass\nimport requests\nimport time\nimport urllib3\nfrom pprint import pprint\n\n\nclass OGGRestAPI:\n    \"\"\"Oracle GoldenGate REST API client (base class).\"\"\"\n\n    # HTTP statuses worth retrying (transient \/ server-side).\n    _RETRY_STATUSES = frozenset({429, 502, 503, 504})\n    # Exceptions worth retrying (transient network issues).\n    _RETRY_EXCEPTIONS = (\n        requests.exceptions.ConnectionError,\n        requests.exceptions.Timeout,\n        requests.exceptions.ChunkedEncodingError,\n    )\n\n    def __init__(self, url, username=None, password=None, deployment=None, ca_cert=None,\n                 reverse_proxy=False, verify_ssl=True, test_connection=True, timeout=None, version='v2'):\n        \"\"\"\n        Initialize Oracle GoldenGate REST API client.\n\n        :param url: Base URL of the OGG REST API. It can be:\n                    'http(s):\/\/hostname:port' without NGINX reverse proxy,\n                    'https:\/\/nginx_host:nginx_port' with NGINX reverse proxy.\n        :param username: service username\n        :param password: service password. If omitted, the user is prompted to\n                         enter it securely (input is not echoed).\n        :param deployment: when reverse proxy is used, the deployment name to use (e.g. 'ogg_test_01')\n        :param ca_cert: path to a trusted CA cert (for self-signed certs)\n        :param reverse_proxy: bool, whether to use NGINX reverse proxy\n        :param verify_ssl: bool, whether to verify SSL certs\n        :param test_connection: if True, will attempt a simple GET on \/services on init\n        :param timeout: request timeout in seconds\n        \"\"\"\n        self.swagger_version = '2026.01.27'\n        self.version = version\n        self.base_url = url\n        self.username = username\n        if password is None:\n            password = getpass.getpass(f'Password for {username or \"OGG REST API\"}: ')\n        self.auth = (self.username, password)\n        self.headers = {'Accept': 'application\/json', 'Content-Type': 'application\/json'}\n        self.deployment = deployment\n        self.reverse_proxy = reverse_proxy\n        self.verify_ssl = ca_cert if ca_cert else verify_ssl\n        self.timeout = timeout\n        self.session = requests.Session()\n        self.session.headers.update(self.headers)\n\n        if not verify_ssl and self.base_url.startswith('https:\/\/'):\n            # Disable InsecureRequestWarning if verification is off\n            urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)\n\n        # Test connection\n        if test_connection:\n            # Verify connectivity. Raises on failure so callers can catch and handle\n            # connection issues gracefully. The base class has no generated endpoint\n            # methods, so a simple GET on \/services is used here.\n            resp = self._request('GET', '\/services', raw_response=True)\n            if resp.status_code == 200:\n                print(f'Connected to OGG REST API at {self.base_url}')\n            elif resp.status_code == 403:\n                raise RuntimeError(\n                    f\"Authentication failed connecting to OGG REST API at {self.base_url} \"\n                    f\"with user {self.username}. Please check your credentials.\"\n                )\n            else:\n                raise RuntimeError(\n                    f\"Failed to connect to OGG REST API at {self.base_url}. \"\n                    f\"HTTP {resp.status_code}: {resp.text}\"\n                )\n\n    def _request(self, method, path, *, params=None, data=None, max_retries=3,\n                 backoff_factor=1.0, raw_response=False):\n        \"\"\"Make an HTTP request, retrying transient failures, then parse the response.\n\n        Retries are attempted for transient network exceptions (connection errors,\n        timeouts, chunked-encoding errors) and for retryable HTTP statuses\n        (429, 502, 503, 504), using exponential backoff. When the server sends a\n        ``Retry-After`` header, that value is honored instead of the computed delay.\n\n        Args:\n            method (str): The HTTP method to use.\n            path (str): The API endpoint path.\n            params (dict, optional): Query parameters for the request. Defaults to None.\n            data (dict, optional): The request body data. Defaults to None.\n            max_retries (int, optional): Maximum number of attempts. Defaults to 3.\n            backoff_factor (float, optional): Base delay (seconds) for exponential\n                backoff. Delay for attempt n is backoff_factor * 2**(n-1). Defaults to 1.0.\n            raw_response (bool, optional): Whether to return the raw response object. Defaults to False.\n\n        Returns:\n            dict or requests.Response: The parsed response or the raw response object.\n        \"\"\"\n        url = f'{self.base_url}{path}'\n        response = None\n        last_exc = None\n        for attempt in range(1, max_retries + 1):\n            try:\n                response = self.session.request(\n                    method,\n                    url,\n                    auth=self.auth,\n                    params=params,\n                    json=data,\n                    verify=self.verify_ssl,\n                    timeout=self.timeout\n                )\n            except self._RETRY_EXCEPTIONS as exc:\n                last_exc = exc\n                if attempt &gt;= max_retries:\n                    raise\n                delay = self._retry_delay(attempt, backoff_factor)\n                print(f\"Request to {url} failed ({exc.__class__.__name__}: {exc}); \"\n                      f\"retrying in {delay:.1f}s (attempt {attempt}\/{max_retries})...\")\n                time.sleep(delay)\n                continue\n\n            # Retry transient server-side statuses while attempts remain.\n            if response.status_code in self._RETRY_STATUSES and attempt &lt; max_retries:\n                delay = self._retry_delay(attempt, backoff_factor, response=response)\n                print(f\"Request to {url} returned HTTP {response.status_code}; \"\n                      f\"retrying in {delay:.1f}s (attempt {attempt}\/{max_retries})...\")\n                time.sleep(delay)\n                continue\n\n            break\n\n        if response is None:\n            # Every attempt raised a network exception; surface the last one.\n            raise last_exc\n\n        if raw_response:\n            return response\n        result = self._parse(response)\n        self._check_response(response, url)\n        return self._extract_main(result)\n\n    def _retry_delay(self, attempt, backoff_factor, response=None):\n        \"\"\"Compute the delay before the next retry.\n\n        Honors a ``Retry-After`` response header (seconds) when present, otherwise\n        falls back to exponential backoff: backoff_factor * 2**(attempt - 1).\n        \"\"\"\n        if response is not None:\n            retry_after = response.headers.get('Retry-After')\n            if retry_after:\n                try:\n                    return float(retry_after)\n                except (TypeError, ValueError):\n                    pass\n        return backoff_factor * (2 ** (attempt - 1))\n\n    def _build_path(self, template, ogg_service=None, path_params=None):\n        path_params = dict(path_params or {})\n        if \"{version}\" in template and \"version\" not in path_params:\n            path_params&#091;\"version\"] = self.version\n\n        # If reverse proxy is enabled, the full service must be added before \/v2\/\n        #   - \/services\/ServiceManager\/v2\/... for Service Manager\n        #   - \/services\/deployment_name\/ogg_service\/v2\/... for other services when a deployment is specified\n        if self.reverse_proxy and template != '\/services':\n            if ogg_service == 'ServiceManager' or not self.deployment:\n                template = f'\/services\/ServiceManager\/{template.removeprefix(\"\/services\/\")}'\n            else:\n                template = f'\/services\/{self.deployment}\/{ogg_service}\/{template.removeprefix(\"\/services\/\")}'\n        return template.format(**path_params)\n\n    def _call(self, method, template, *, ogg_service=None, path_params=None, params=None,\n              data=None, body_params=None, raw_response=False, if_exists='fail'):\n        if self.reverse_proxy and ogg_service == '' and self.deployment:\n            # This is a common endpoint and a deployment is specified. Choosing adminsrvr service by default.\n            ogg_service = \"adminsrvr\"\n        path = self._build_path(template, ogg_service=ogg_service, path_params=path_params)\n        url = f'{self.base_url}{path}'\n\n        # Merge body_params into data when provided. body_params is a dict mapping\n        # payload field names to values (the generated methods pass their\n        # explicit body params here). Only merge when `data` is a dict or None.\n        if body_params:\n            if data is None:\n                data = {}\n            if isinstance(data, dict):\n                # Copy first so the caller's dict is never mutated.\n                data = dict(data)\n                for k, v in body_params.items():\n                    if v is not None:\n                        data&#091;k] = v\n            if not data:\n                data = None\n\n        # If caller asked to skip on existing resource, inspect the raw response and\n        # treat a 409 (already exists) as a no-op instead of an error. Routing through\n        # _request means this path inherits the same retry handling as normal calls.\n        if if_exists == 'skip':\n            response = self._request(method, path, params=params, data=data, raw_response=True)\n            parsed = self._parse(response)\n\n            if response.status_code == 409:\n                titles = &#091;]\n                if isinstance(parsed, dict):\n                    for m in parsed.get('messages', &#091;]):\n                        if isinstance(m, dict) and m.get('title'):\n                            titles.append(m&#091;'title'])\n                message = '; '.join(titles) if titles else 'Resource exists'\n                print(f\"{message} (if_exists set to skip)\")\n                return {'status': 'skipped', 'message': message, 'http_status': 409, 'raw': parsed}\n\n            # Otherwise behave like normal _call: raise on errors, return parsed or extracted\n            self._check_response(response, url)\n            if raw_response:\n                return parsed\n            return self._extract_main(parsed)\n\n        # Default behavior: use existing request flow\n        result = self._request(method, path, params=params, data=data, raw_response=raw_response)\n        return result\n\n    def _get(self, path, params=None, raw_response=False):\n        return self._request('GET', path, params=params, raw_response=raw_response)\n\n    def _post(self, path, data=None, raw_response=False):\n        return self._request('POST', path, data=data, raw_response=raw_response)\n\n    def _put(self, path, data=None, raw_response=False):\n        return self._request('PUT', path, data=data, raw_response=raw_response)\n\n    def _patch(self, path, data=None, raw_response=False):\n        return self._request('PATCH', path, data=data, raw_response=raw_response)\n\n    def _delete(self, path, raw_response=False):\n        return self._request('DELETE', path, raw_response=raw_response)\n\n    def _check_response(self, response, url):\n        if response.ok:\n            return\n\n        # Parse the body once; _parse returns text (not a dict) for non-JSON bodies.\n        body = self._parse(response)\n        messages = body.get('messages') if isinstance(body, dict) else None\n        if messages:\n            error_messages = &#091;]\n            for message in messages:\n                if isinstance(message, dict):\n                    severity = message.get('severity', 'ERROR')\n                    title = message.get('title', message)\n                else:\n                    severity, title = 'ERROR', message\n                error_messages.append(\n                    f\"{severity} (code {response.status_code}) - {url}: {title}\"\n                )\n            raise RuntimeError(' ; '.join(error_messages))\n\n        print(f'HTTP {response.status_code}: {response.text}')\n        response.raise_for_status()\n\n    def _parse(self, response):\n        try:\n            return response.json()\n        except ValueError:\n            return response.text\n\n    def close(self):\n        self.session.close()\n\n    def __enter__(self):\n        return self\n\n    def __exit__(self, *_exc):\n        self.close()\n        return False\n\n    def _extract_main(self, result):\n        if not isinstance(result, dict):\n            return result\n\n        resp = result.get('response', result)\n        if 'items' not in resp:\n            return resp\n\n        exclude = {'links', '$schema'}\n        return &#091;{k: v for k, v in i.items() if k not in exclude} for i in resp&#091;'items']]\n\n    def pretty_print(self, result):\n        pprint(result)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">While this is already <strong>useful when starting<\/strong> with GoldenGate automation, <strong>searching for the correct endpoints<\/strong> and methods or providing the correct parameters can quickly become daunting. That is why I decided to build and release an <strong>easy-to-use Python client<\/strong> for the GoldenGate REST API.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To make things easier for developers, REST APIs often come with some sort of standard template file that will guide the user on how to query the API and interpret the results. Oracle provides a <code>swagger.json<\/code> file, which you can get for GoldenGate <a href=\"https:\/\/docs.oracle.com\/en\/database\/goldengate\/core\/26\/oggra\/swagger.json\" target=\"_blank\" rel=\"noreferrer noopener\">26ai<\/a> and <a href=\"https:\/\/docs.oracle.com\/en\/middleware\/goldengate\/core\/19.1\/oggra\/swagger.json\" target=\"_blank\" rel=\"noreferrer noopener\">19c<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are multiple ways online to transform these <code>Swagger<\/code> files into working Python clients, but they are very often not tailored to the specific needs of the API, and unusable in practice. Hence my proposal with this blog post.<\/p>\n\n\n\n<h2 id=\"h-example-of-a-rest-api-method-in-the-client\" class=\"wp-block-heading\">Example of a REST API method in the client<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">There are around 300 methods included in the client that I provide. Here is an example with the <code>create_alias<\/code> method.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Endpoint: \/services\/{version}\/authorizations\/{role}\/{user}\ndef create_user(\n    self,\n    role,\n    user,\n    data=None,\n    ogg_service='',\n    raw_response=False,\n    if_exists='fail'\n):\n    \"\"\"\n    Common\/User Management\n    POST \/services\/{version}\/authorizations\/{role}\/{user}\n    Required Role: Security\n    Create a new Authorization User Resource.\n\n    Parameters:\n        role (str): Authorization Role Resource Name. Required. Example: User\n        user (str): User Resource Name. Required. Example: user_example\n        data (dict): Data payload. See call example below for more details.\n        ogg_service (str): The service name to use for the request. It is only needed when using a\n            reverse proxy. Example: ogg_service_example\n        raw_response (bool): If True, return raw parsed response from _parse() instead of\n            _extract_main().\n        if_exists (str): Action if resource exists: 'fail' (error) or 'skip' (no action). Example:\n            if_exists_example\n\n    Example:\n        client.create_user(\n            role='User',\n            user='user_example',\n            ogg_service='adminsrvr',\n            data={\n                \"credential\": \"password-A1\",\n                \"info\": \"Credential Information\"\n            }\n        )\n    \"\"\"\n    return self._call(\n        method=\"POST\",\n        template=\"\/services\/{version}\/authorizations\/{role}\/{user}\",\n        path_params={\n            \"role\": role,\n            \"user\": user,\n        },\n        data=data,\n        ogg_service=ogg_service,\n        if_exists=if_exists,\n        raw_response=raw_response\n    )<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">With this method, you can easily create an alias in GoldenGate with the following code. But more on that later.<\/p>\n\n\n\n<h2 id=\"h-where-to-find-the-code\" class=\"wp-block-heading\">Where to find the code ?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The full code is available in this <a href=\"https:\/\/github.com\/juliendlttr\/ogg\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub repository<\/a>. Feel free to use it in your deployments. I provided one Python class for GoldenGate 26ai, one for 23ai (if you are still using it) and another one for GoldenGate 19c. For the most basic functions, there is not much difference between the clients, but for more advanced usage, I would suggest using the code dedicated to the proper version of GoldenGate.<\/p>\n\n\n\n<h2 id=\"h-how-to-use-the-client\" class=\"wp-block-heading\">How to use the client ?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Administering your GoldenGate deployments with this client is straightforward. Just start by importing the class and creating a client instance.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from oggrestapi import OGGRestAPI\n\n# Connect to http:\/\/vmogg:7809 with user 'ogg'\nogg_client = OGGRestAPI(host=\"vmogg\", port=7809, username=\"ogg\", password=\"ogg\", protocol=\"http\")<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you would rather not hardcode the password, simply omit it and you will be prompted to enter it securely (the input is not echoed):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&amp;gt;&amp;gt;&amp;gt; ogg_client = OGGRestAPI(url=&quot;http:\/\/vmogg:7809&quot;, username=&quot;ogg&quot;)\nPassword for ogg:\nConnected to OGG REST API at http:\/\/vmogg:7809\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The client also supports the context-manager protocol, so the underlying HTTP session is always closed for you:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nwith OGGRestAPI(url=&quot;http:\/\/vmogg:7809&quot;, username=&quot;ogg&quot;) as ogg_client:\n    print(ogg_client.list_deployments())\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The connection status is displayed when the client is initialized:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt;&gt; from oggrestapi import OGGRestAPI\n&gt;&gt;&gt; ogg_client = OGGRestAPI(url=\"http:\/\/vmogg:7809\", username=\"ogg\", password=\"ogg\")\nConnected to OGG REST API at http:\/\/vmogg:7809<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To illustrate the benefits of using this client, here is what a standard API call to create a GoldenGate user would look like with Python.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import requests\n\nrole = \"User\"\nuser = \"ogg_username\"\nurl = f\"http:\/\/vmogg:7809\/services\/v2\/authorizations\/{role}\/{user}\"\nauth = (\"ogg_user\", \"ogg_password\")\ndata = {\n    \"credential\": \"your_password\"\n}\n\nresult = requests.post(url, auth=auth, json=data)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The same operation using the Python client becomes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ogg_client.create_user(\n    user=\"ogg_username\",\n    role=\"User\",\n    data={\"credential\": \"your_password\"}\n)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">All endpoint parameters (such as <code>user<\/code> and <code>role<\/code>, in the example above) are now method arguments (<code>create_user<\/code>, in this case). To keep things simple and not over-engineer, the <code>data<\/code> payload of the API is kept. But depending on the endpoint, you could easily add wrapper functions to further simplify usage.<\/p>\n\n\n\n<h2 id=\"h-call-examples\" class=\"wp-block-heading\">Call examples<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I give below a few other basic calls that you can use. You should pay attention to the port you are using when making calls to the API. Some endpoints are only accessible on specific services. For instance, <code>list_extracts<\/code> will only work on the administration service of a deployment (default port 7810), while <code>list_deployments<\/code> only works on the service manager (default port 7809).<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>List deployments associated with a service manager.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt;&gt; ogg_client.list_deployments()\n&#091;{'name': 'ServiceManager', 'status': 'running'}, {'name': 'ogg_test_01', 'status': 'running'}]<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>List extracts in a deployment (for this one, <code>ogg_client<\/code> has to be created on the administration service of the deployment if you are not using an NGINX proxy).<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt;&gt; ogg_client.list_extracts()\n&#091;{'name': 'EXT01', 'status': 'stopped'}, {'name': 'EXT02', 'status': 'running'}, {'name': 'EXT03', 'status': 'running'}]<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>List and get tasks<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt;&gt; ogg_client.list_tasks()\n&#091;{'name': 'purge_aa'}]\n\n&gt;&gt;&gt; ogg_client.get_task('purge_aa')\n{'enabled': True, 'critical': False, 'status': 'stopped', 'command': {'name': 'purge', 'purgeType': 'trails', 'useCheckpoints': True, 'trails': &#091;{'name': 'aa', 'path': 'PDB1'}], 'keep': &#091;{'type': 'min', 'value': 48, 'units': 'hours'}]}, 'schedule': {'every': {'units': 'days', 'value': 1}}, 'restart': {'enabled': False}, '$schema': 'ogg:task'}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And of course, you can create and manage extracts, replicats, etc. through this client. All tasks available through the API are replicated in the client.<\/p>\n\n\n\n<h2 id=\"h-method-naming-explanation\" class=\"wp-block-heading\">Method naming explanation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I only wrote this section of the blog for those who would like to dig a bit deeper. Method names are generated from the Swagger definition and then&nbsp;<strong>normalized for consistency<\/strong>&nbsp;through a curated mapping, so that the same action always uses the same verb across the whole client:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>list_<\/code><\/strong>&nbsp;for endpoints returning a collection (e.g.&nbsp;<code>list_deployments<\/code>,&nbsp;<code>list_extracts<\/code>,&nbsp;<code>list_users<\/code>).<\/li>\n\n\n\n<li><strong><code>get_<\/code><\/strong>&nbsp;for endpoints returning a single resource or its details (e.g.&nbsp;<code>get_extract<\/code>,&nbsp;<code>get_task<\/code>).<\/li>\n\n\n\n<li><strong><code>create_<\/code>&nbsp;\/&nbsp;<code>update_<\/code>&nbsp;\/&nbsp;<code>delete_<\/code><\/strong>&nbsp;for the corresponding&nbsp;<code>POST<\/code>&nbsp;\/&nbsp;<code>PATCH<\/code>&#8211;<code>PUT<\/code>&nbsp;\/&nbsp;<code>DELETE<\/code>&nbsp;operations (e.g.&nbsp;<code>create_user<\/code>,&nbsp;<code>update_extract<\/code>,&nbsp;<code>delete_user<\/code>).<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This naming is built using three layers:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I only wrote this section of the blog for those who would like to dig a bit deeper. I generated the method names using three different layers:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The basic method name comes from the&nbsp;<strong>summary given by Oracle<\/strong>, normalized to the verbs above. For instance, the &#8220;Create an Alias&#8221; summary is associated with the&nbsp;<code>create_alias<\/code>&nbsp;method. Words like&nbsp;<em><strong><code>a<\/code><\/strong><\/em>,&nbsp;<em><strong><code>an<\/code><\/strong><\/em>&nbsp;or&nbsp;<em><strong><code>of<\/code><\/strong><\/em>&nbsp;are removed from the name. This way, the vast majority of methods have a very simple and canonical name that is easy to remember or to retrieve from the documentation.<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"230\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_create_alias-1024x230.png\" alt=\"\" class=\"wp-image-42284\" style=\"width:auto;height:150px\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_create_alias-1024x230.png 1024w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_create_alias-300x67.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_create_alias-768x173.png 768w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_create_alias.png 1104w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n\n\n<ul class=\"wp-block-list\">\n<li>Unfortunately, some methods still share the same summary. A good example is the &#8220;<em><strong>Retrieve Status<\/strong><\/em>&#8221; summary, which is available for both&nbsp;<strong>extracts<\/strong>&nbsp;and&nbsp;<strong>replicats<\/strong>. To avoid a collision, the resource is added to the name. In this specific case, there is no&nbsp;<code>get_status<\/code>&nbsp;method, but there are&nbsp;<code>get_extract_status<\/code>&nbsp;and&nbsp;<code>get_replicat_status<\/code>&nbsp;methods.<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"199\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_retrieve_status_extract-1024x199.png\" alt=\"\" class=\"wp-image-42285\" style=\"width:auto;height:150px\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_retrieve_status_extract-1024x199.png 1024w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_retrieve_status_extract-300x58.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_retrieve_status_extract-768x149.png 768w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_retrieve_status_extract.png 1142w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"197\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_retrieve_status_replicat-1024x197.png\" alt=\"\" class=\"wp-image-42286\" style=\"width:auto;height:150px\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_retrieve_status_replicat-1024x197.png 1024w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_retrieve_status_replicat-300x58.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_retrieve_status_replicat-768x147.png 768w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_retrieve_status_replicat.png 1188w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n\n\n<ul class=\"wp-block-list\">\n<li>More than 99% of methods are covered by the first two cases. When that is not enough \u2014 like the &#8220;<em><strong>Get a list of distribution paths<\/strong><\/em>&#8221; summary, which exists for both source and target paths \u2014 the names are disambiguated by their role. Source paths are listed with&nbsp;<code>list_distribution_paths<\/code>&nbsp;(endpoint&nbsp;<code>\/sources<\/code>), while target paths are listed with&nbsp;<code>list_receiver_paths<\/code>&nbsp;(endpoint&nbsp;<code>\/targets<\/code>).<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"710\" height=\"230\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_get_distpath_target.png\" alt=\"\" class=\"wp-image-42287\" style=\"width:auto;height:150px\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_get_distpath_target.png 710w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_get_distpath_target-300x97.png 300w\" sizes=\"auto, (max-width: 710px) 100vw, 710px\" \/><\/figure>\n<\/div>\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"702\" height=\"222\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_get_distpath_source.png\" alt=\"\" class=\"wp-image-42288\" style=\"width:auto;height:150px\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_get_distpath_source.png 702w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_get_distpath_source-300x95.png 300w\" sizes=\"auto, (max-width: 702px) 100vw, 702px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">In upcoming blog posts, I will provide concrete examples on how to manage your GoldenGate deployments from A to Z with this client. In the meantime, do not hesitate if you have any feedback on this little project !<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Updated in June 2026, based on the latest version of the client. In this blog, I provide GoldenGate administrators with a fully working, production-ready Python client to efficiently handle GoldenGate REST API calls. From extract creation to user management, it has never been easier to manage and monitor your GoldenGate deployments ! Basic OGGRestAPI Python [&hellip;]<\/p>\n","protected":false},"author":152,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[3787,59],"tags":[3380,3182,3560,3827,3804,979,708,1257,328,3229,1089,1521,3767],"type_dbi":[3835,3826,3406,3828,3823,3801,3817,3836,3740,3231,3768,3800,3769],"class_list":["post-42345","post","type-post","status-publish","format-standard","hentry","category-goldengate","category-oracle","tag-3380","tag-3182","tag-23ai","tag-3827","tag-26ai","tag-api","tag-automation","tag-client","tag-goldengate","tag-microservices","tag-python","tag-rest","tag-restapi","type-3835","type-3826","type-23ai","type-3828","type-26ai","type-api","type-automation","type-client","type-goldengate","type-microservices","type-python","type-rest","type-restapi"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.8 (Yoast SEO v27.8) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Production-ready GoldenGate REST client in Python - dbi Blog<\/title>\n<meta name=\"description\" content=\"Get the most of your GoldenGate deployments with this easy-to-use production-ready REST API Python client !\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Production-ready GoldenGate REST client in Python\" \/>\n<meta property=\"og:description\" content=\"Get the most of your GoldenGate deployments with this easy-to-use production-ready REST API Python client !\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-02-23T07:24:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-06-28T03:59:40+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_create_alias.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1104\" \/>\n\t<meta property=\"og:image:height\" content=\"248\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Julien Delattre\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Julien Delattre\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/production-ready-goldengate-rest-client-in-python\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/production-ready-goldengate-rest-client-in-python\\\/\"},\"author\":{\"name\":\"Julien Delattre\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/764ab019cc9dec42655b4c6b9b8e474e\"},\"headline\":\"Production-ready GoldenGate REST client in Python\",\"datePublished\":\"2026-02-23T07:24:00+00:00\",\"dateModified\":\"2026-06-28T03:59:40+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/production-ready-goldengate-rest-client-in-python\\\/\"},\"wordCount\":1019,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/production-ready-goldengate-rest-client-in-python\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2025\\\/12\\\/ogg_restapi_create_alias-1024x230.png\",\"keywords\":[\"19\",\"23\",\"23ai\",\"26\",\"26ai\",\"api\",\"Automation\",\"Client\",\"GoldenGate\",\"microservices\",\"Python\",\"rest\",\"restapi\"],\"articleSection\":[\"GoldenGate\",\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/production-ready-goldengate-rest-client-in-python\\\/#respond\"]}],\"accessibilityFeature\":[\"tableOfContents\"]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/production-ready-goldengate-rest-client-in-python\\\/\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/production-ready-goldengate-rest-client-in-python\\\/\",\"name\":\"Production-ready GoldenGate REST client in Python - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/production-ready-goldengate-rest-client-in-python\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/production-ready-goldengate-rest-client-in-python\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2025\\\/12\\\/ogg_restapi_create_alias-1024x230.png\",\"datePublished\":\"2026-02-23T07:24:00+00:00\",\"dateModified\":\"2026-06-28T03:59:40+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/764ab019cc9dec42655b4c6b9b8e474e\"},\"description\":\"Get the most of your GoldenGate deployments with this easy-to-use production-ready REST API Python client !\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/production-ready-goldengate-rest-client-in-python\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/production-ready-goldengate-rest-client-in-python\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/production-ready-goldengate-rest-client-in-python\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2025\\\/12\\\/ogg_restapi_create_alias.png\",\"contentUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2025\\\/12\\\/ogg_restapi_create_alias.png\",\"width\":1104,\"height\":248},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/production-ready-goldengate-rest-client-in-python\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Production-ready GoldenGate REST client in Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/764ab019cc9dec42655b4c6b9b8e474e\",\"name\":\"Julien Delattre\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a97d00e680bbf237126e24b65281cbcb66cd20bd1ed2d14bf928991b2bf68eb5?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a97d00e680bbf237126e24b65281cbcb66cd20bd1ed2d14bf928991b2bf68eb5?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a97d00e680bbf237126e24b65281cbcb66cd20bd1ed2d14bf928991b2bf68eb5?s=96&d=mm&r=g\",\"caption\":\"Julien Delattre\"},\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/author\\\/juliendelattre\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Production-ready GoldenGate REST client in Python - dbi Blog","description":"Get the most of your GoldenGate deployments with this easy-to-use production-ready REST API Python client !","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/","og_locale":"en_US","og_type":"article","og_title":"Production-ready GoldenGate REST client in Python","og_description":"Get the most of your GoldenGate deployments with this easy-to-use production-ready REST API Python client !","og_url":"https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/","og_site_name":"dbi Blog","article_published_time":"2026-02-23T07:24:00+00:00","article_modified_time":"2026-06-28T03:59:40+00:00","og_image":[{"width":1104,"height":248,"url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_create_alias.png","type":"image\/png"}],"author":"Julien Delattre","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Julien Delattre","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/"},"author":{"name":"Julien Delattre","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/764ab019cc9dec42655b4c6b9b8e474e"},"headline":"Production-ready GoldenGate REST client in Python","datePublished":"2026-02-23T07:24:00+00:00","dateModified":"2026-06-28T03:59:40+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/"},"wordCount":1019,"commentCount":0,"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_create_alias-1024x230.png","keywords":["19","23","23ai","26","26ai","api","Automation","Client","GoldenGate","microservices","Python","rest","restapi"],"articleSection":["GoldenGate","Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/#respond"]}],"accessibilityFeature":["tableOfContents"]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/","url":"https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/","name":"Production-ready GoldenGate REST client in Python - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/#primaryimage"},"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_create_alias-1024x230.png","datePublished":"2026-02-23T07:24:00+00:00","dateModified":"2026-06-28T03:59:40+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/764ab019cc9dec42655b4c6b9b8e474e"},"description":"Get the most of your GoldenGate deployments with this easy-to-use production-ready REST API Python client !","breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/#primaryimage","url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_create_alias.png","contentUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/12\/ogg_restapi_create_alias.png","width":1104,"height":248},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/production-ready-goldengate-rest-client-in-python\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Production-ready GoldenGate REST client in Python"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/764ab019cc9dec42655b4c6b9b8e474e","name":"Julien Delattre","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/a97d00e680bbf237126e24b65281cbcb66cd20bd1ed2d14bf928991b2bf68eb5?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/a97d00e680bbf237126e24b65281cbcb66cd20bd1ed2d14bf928991b2bf68eb5?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a97d00e680bbf237126e24b65281cbcb66cd20bd1ed2d14bf928991b2bf68eb5?s=96&d=mm&r=g","caption":"Julien Delattre"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/juliendelattre\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/42345","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/152"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=42345"}],"version-history":[{"count":27,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/42345\/revisions"}],"predecessor-version":[{"id":45423,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/42345\/revisions\/45423"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=42345"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=42345"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=42345"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=42345"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}