Skip to main content

🌉 ApexRestpy

Oracle APEX RESTful API Client — Python

A Python Adaptation of the ApexBridge C++ Arduino Library


CI Release PyPI version Python Versions codecov Ruff Checked with mypy License: ApacheV2 Downloads


📋 Table of Contents


🎯 Executive Summary

ApexRestpy is a lightweight, minimal-dependency (only requests) client library that enables Python applications to communicate swiftly with Oracle APEX RESTful services. It is a direct Python adaptation of the ApexBridge library written in C++ for microcontrollers (ESP32/ESP8266); you can use the same logical API on servers, Raspberry Pi, automation scripts, and CI/CD pipelines.

The library abstracts Oracle APEX's standard /<base_path>/<schema>/<module>/<resource> URL structure and provides Bearer token authentication, query parameter management, and all HTTP methods (GET/POST/PUT/PATCH/DELETE) through a unified, easy-to-test interface. HTTPS connections are established with zero configuration; SSL certificate management is handled entirely and automatically by requests + certifi.

Target audience: Python developers using Oracle APEX as a backend, IoT integration engineers, and embedded systems developers migrating from the Arduino ecosystem to Python.


✨ Key Features

Feature Description
🔗 Seamless APEX Communication Automatic endpoint construction with the schema/module/resource URL pattern
🔒 Automatic HTTPS Zero-configuration SSL via requests + certifi — no manual certificates
🔑 Bearer Token Authentication One-line OAuth/JWT integration with set_token()
🛠️ Full HTTP Support GET · POST · PUT · PATCH · DELETE
🧩 Fluent URL Management Chainable API: prepare_url() + add_parameter() + add_path()
🐍 Pythonic Design snake_case, @dataclass, type hints, logging module
⚡ Lightweight Single external dependency: requests>=2.28
🧪 High Test Coverage 38 unit tests, mocked HTTP — no real network required
🔄 Session Management Connection reuse via requests.Session
📦 Installable Standard PyPI installation with pip install apex-restpy

🏗️ Architecture & Flow

ApexRestpy acts as a thin abstraction layer between your application and the Oracle APEX server:

flowchart LR
    subgraph Application["Your Application"]
        direction TB
        A["bridge = ApexBridge(schema)"]
        B["bridge.set_token(token)"]
        C["bridge.prepare_url(module, resource)"]
        D["bridge.add_parameter(k, v)"]
        E["bridge.send_request('GET')"]
    end

    subgraph ApexRestpy["apex_restpy Layer"]
        direction TB
        AB["ApexBridge"]
        APP["ApexApp @dataclass"]
        EXC["ApexConnectionError\nApexResponseError"]
        AB --> APP
        AB --> EXC
    end

    subgraph HTTP["HTTP Layer"]
        REQ["requests.Session\n(HTTPS + certifi)"]
    end

    subgraph APEX["Oracle APEX"]
        ORDS["APEX REST Services\nhttps://apex.oracle.com/pls/apex/\n{schema}/{module}/{resource}"]
    end

    Application --> ApexRestpy
    ApexRestpy --> HTTP
    HTTP -->|"HTTPS GET/POST/PUT/PATCH/DELETE"| APEX
    APEX -->|"JSON Response"| HTTP
    HTTP -->|"dict"| ApexRestpy
    ApexRestpy -->|"dict"| Application

URL Construction Process

ApexApp.base_path  +  schema   +  module  +  resource  [?param=val&...]  [/path]
    /pls/apex      /  myschema /  sensor  /   data     ?id=42&type=temp  /details

→ https://apex.oracle.com/pls/apex/myschema/sensor/data/details?id=42&type=temp

Package Structure

apex_restpy/
├── __init__.py          # Public API: ApexBridge, ApexApp, exceptions
├── apex_bridge.py       # Core client class
├── apex_app.py          # Configuration dataclass
└── exceptions.py        # ApexConnectionError, ApexResponseError

tests/
└── test_apex_bridge.py  # 38 unit tests (mocked HTTP)

examples/
├── basic_get.py         # GET example
└── basic_post.py        # POST example

🛠️ Tech Stack

Layer Technology Version
Language Python ≥ 3.9
HTTP Client requests ≥ 2.28.0
SSL certifi (requests dependency) Automatic
Packaging setuptools + pyproject.toml PEP 517/518
Lint Ruff ≥ 0.4.0
Type Checking mypy ≥ 1.8.0
Testing pytest + pytest-cov ≥ 7.0 / ≥ 4.0
CI/CD GitHub Actions —
Release Management Release Please v4
Dependency Updates Dependabot —

✅ Prerequisites

The following tools must be installed in your development environment:

Tool Minimum Version Check
Python 3.9 python --version
pip 21.0 pip --version
Git 2.30 git --version

🚀 Installation

pip install apex-restpy

Development Setup

# 1. Clone the repository
git clone https://github.com/AtaCanYmc/ApexRestpy.git
cd ApexRestpy

# 2. Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate        # Linux / macOS
# .venv\Scripts\activate.bat     # Windows CMD
# .venv\Scripts\Activate.ps1     # Windows PowerShell

# 3. Install the package with development dependencies
pip install -e ".[dev]"

Verify Installation

python -c "from apex_restpy import ApexBridge; print('✅ apex-restpy is ready!')"

⚡ Quick Start

from apex_restpy import ApexBridge

# 1. Initialise the bridge
bridge = ApexBridge(schema="myschema")

# 2. (Optional) Set the authentication token
bridge.set_token("your-jwt-bearer-token")

# 3. Prepare the endpoint and send a request
bridge.prepare_url("time", "now")
response = bridge.send_request()   # default: GET

# 4. Use the response
print(response["full_timestamp"])  # → "2025-03-02T14:30:00"
print(response["year"])            # → 2025

📖 Usage & API Reference

ApexBridge(schema, base_path, host, timeout, debug, session)

The core client class. All APEX communication is handled through this object.

bridge = ApexBridge(
    schema="myschema",          # APEX workspace schema name (required)
    base_path="/pls/apex",      # URL prefix (default: "/pls/apex")
    host="apex.oracle.com",     # APEX server address (default)
    timeout=10.0,               # Request timeout in seconds (default: 10)
    debug=False,                # If True, enables DEBUG log level
)

set_token(token: str)

Enables Bearer token authentication. The Authorization: Bearer <token> header is automatically added to all subsequent requests.

bridge.set_token("eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...")

prepare_url(module, resource, schema=None) → str

Constructs the APEX REST endpoint path and stores it in the internal _last_endpoint.

url = bridge.prepare_url("sensor", "data")
# → "/pls/apex/myschema/sensor/data"

# With a different schema
url = bridge.prepare_url("time", "now", schema="otherschema")
# → "/pls/apex/otherschema/time/now"

add_parameter(param, value, url=None) → str

Appends a query parameter to the active endpoint (or a given URL).

bridge.prepare_url("sensor", "data")
bridge.add_parameter("id", "42")       # → ...?id=42
bridge.add_parameter("type", "temp")   # → ...?id=42&type=temp

# On a custom URL (the stored endpoint is not modified)
result = bridge.add_parameter("limit", "10", url="/pls/apex/myschema/items/list")
# → "/pls/apex/myschema/items/list?limit=10"

add_path(path, url=None) → str

Appends an additional path segment to the active endpoint.

bridge.prepare_url("items", "list")
bridge.add_path("active")
# _last_endpoint → "/pls/apex/myschema/items/list/active"

send_request(method="GET", payload=None, url=None) → dict

Sends an HTTP request and returns the JSON response as a dict.

# GET
response = bridge.send_request()

# POST — with a JSON body
response = bridge.send_request(
    method="POST",
    payload={"sensor_id": "42", "value": 23.5},
)

# PUT, PATCH, DELETE
bridge.send_request("PUT",   payload={"name": "updated"})
bridge.send_request("PATCH", payload={"status": "active"})
bridge.send_request("DELETE")

# Request to a different URL (the stored endpoint is not modified)
response = bridge.send_request("GET", url="/pls/apex/myschema/custom/path")

Supported methods: GET · POST · PUT · PATCH · DELETE


Exceptions

Exception When raised
ApexConnectionError Network connection cannot be established or times out
ApexResponseError Response body is not valid JSON
ValueError An unsupported HTTP method is provided
from apex_restpy import ApexBridge, ApexConnectionError, ApexResponseError

try:
    response = bridge.send_request()
except ApexConnectionError as e:
    print(f"Connection error: {e}")
except ApexResponseError as e:
    print(f"Invalid response: {e}")

Full Scenario Example

from apex_restpy import ApexBridge

bridge = ApexBridge(schema="iot_prod", timeout=15.0, debug=True)
bridge.set_token("your-jwt-token")

# Fetching data with pagination and filtering
bridge.prepare_url("sensors", "readings")
bridge.add_parameter("device_id", "esp32-01")
bridge.add_parameter("limit", "100")
bridge.add_path("latest")
# → /pls/apex/iot_prod/sensors/readings/latest?device_id=esp32-01&limit=100

response = bridge.send_request("GET")

for reading in response.get("items", []):
    print(f"{reading['ts']} → {reading['value']} {reading['unit']}")

🔐 Environment Variables

ApexRestpy is a library, not a CLI tool or service, so it does not ship its own .env file. For applications that use credentials, we recommend the following pattern:

.env.example — Reference this file in your project:

# Oracle APEX Configuration
APEX_SCHEMA=your_schema_name
APEX_BASE_PATH=/pls/apex
APEX_HOST=apex.oracle.com
APEX_TIMEOUT=10

# Authentication
APEX_BEARER_TOKEN=your_jwt_or_oauth_token

Usage:

import os
from dotenv import load_dotenv
from apex_restpy import ApexBridge

load_dotenv()

bridge = ApexBridge(
    schema=os.environ["APEX_SCHEMA"],
    host=os.environ.get("APEX_HOST", "apex.oracle.com"),
    timeout=float(os.environ.get("APEX_TIMEOUT", "10")),
)
bridge.set_token(os.environ["APEX_BEARER_TOKEN"])

🧪 Testing

Running the Tests

# Run all tests
pytest tests/ -v

# With a coverage report
pytest tests/ -v --cov=apex_restpy --cov-report=term-missing

# HTML coverage report
pytest tests/ --cov=apex_restpy --cov-report=html
open htmlcov/index.html

Test Matrix

tests/
└── test_apex_bridge.py               38 tests
    ├── TestPrepareUrl                  4 tests  — URL construction logic
    ├── TestAddParameter                5 tests  — Query string management
    ├── TestAddPath                     3 tests  — Path appending
    ├── TestSetToken                    4 tests  — Token and header management
    ├── TestSendRequestGet              5 tests  — GET requests
    ├── TestSendRequestPost             3 tests  — POST requests and payload
    ├── TestSendRequestOtherMethods     4 tests  — PUT / PATCH / DELETE
    ├── TestErrorHandling               3 tests  — Error handling
    ├── TestBuildFullUrl                3 tests  — URL normalisation
    └── TestProperties                  4 tests  — Read-only properties

Lint & Type Checking

# Lint
ruff check .

# Format check
ruff format --check .

# Auto-fix formatting
ruff format .

# Type checking
mypy apex_restpy --ignore-missing-imports

🤝 Contributing

We warmly welcome contributions! See CONTRIBUTING.md for the detailed guide.

Quick Start

# 1. Fork and clone
git clone https://github.com/<your-username>/ApexRestpy.git
cd ApexRestpy

# 2. Set up the development environment
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

# 3. Create a feature branch
git checkout -b feat/my-feature

# 4. Make your changes and run the tests
pytest tests/ -v

# 5. Lint and format check
ruff check . && ruff format --check . && mypy apex_restpy

# 6. Write your commit message in Conventional Commits format
git commit -m "feat: add retry mechanism for connection failures"

# 7. Open a PR
git push origin feat/my-feature

Commit Message Conventions

This project uses the Conventional Commits standard:

Prefix Usage
feat: New feature
fix: Bug fix
docs: Documentation only
test: Adding or fixing tests
refactor: Code restructuring
chore: Dependency updates, CI
BREAKING CHANGE: Backwards-incompatible change

Release Please analyses these messages to automatically generate a CHANGELOG and assign version numbers.

Code Standards

  • Formatter: Ruff (line-length = 100)
  • Linter: Ruff (rules E, W, F, I, B, UP)
  • Type checking: mypy (warn_return_any = true)
  • Test coverage: Unit tests are mandatory for new features
  • Docstrings: All public methods must have Google-style docstrings

🔒 Security Policy

For security vulnerability reports, please read SECURITY.md.

In brief: Report vulnerabilities directly to atacanymc@gmail.com, not via GitHub Issues. A fix is committed within 90 days.


📜 License & Contact

This project is distributed under the Apache License. See the LICENSE file for details.


Ata Can Yaymacı

Medium GitHub Email


C++ original: ApexBridge — Arduino library for ESP32/ESP8266

⭐ If you find this useful, don't forget to star it on GitHub!

Metadata

Release files for apex-restpy 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for apex-restpy 0.1.0
File Size Uploaded Provenance Actions
apex_restpy-0.1.0.tar.gz 28.8 kB With provenance Details for apex_restpy-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for apex-restpy 0.1.0
File Interpreter ABI Platform Actions
apex_restpy-0.1.0-py3-none-any.whl Python 3 none any Details for apex_restpy-0.1.0-py3-none-any.whl

Total release size: 49.3 kB

Release files / apex_restpy-0.1.0.tar.gz

Download URL apex_restpy-0.1.0.tar.gz
Size 28.8 kB
Tags Source
SHA-256 checksum
How to use checksums
50b9da6978fd68ea3290efc0e71fbcc7a18c9a5c1b91ccbf86eecf7faece1d2c
BLAKE2b-256 checksum
How to use checksums
8b4117138ee6c17ba2b77899a0646123bb1450e87eb1473dd326ebfb0d85044c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 19, 2026.

Transparency log

Release files / apex_restpy-0.1.0-py3-none-any.whl

Download URL apex_restpy-0.1.0-py3-none-any.whl
Size 20.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ced5eee25b68339ffdd48ea004c806ddd175ddbdde385a77bbc47a4b13f11aa7
BLAKE2b-256 checksum
How to use checksums
19fd39877b40f65a50984b3c0101879fcd9959b3cc0e0ac9e08325dccb46b364
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 19, 2026.

Transparency log

Security for apex-restpy 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for apex_restpy-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 19, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page