Skip to main content

pyrfcx

pyrfcx is an SAP NW RFC client for Python with a Rust core. It installs the import package pyrfc, a drop-in replacement for the client part of SAP's pyrfc 3.4, which SAP has archived. The pyrfc package reproduces the quirks of pyrfc 3.4, each one measured on real pyrfc first.

How it ships:

  • Install with pip, no compiler. pyrfc 3.4 is not on PyPI. It needs a build from source for each CPython version.
  • New CPython versions run without a new release. One abi3 wheel runs on CPython 3.10 and later. Tested from 3.10 to 3.15.
  • New SDK patch levels run without a change. pyrfcx loads the SDK at run time. Tested from 7.50 patch level 11 to 20.

Limits: client only, standard (GIL) CPython only. A call releases the GIL during network operations.

Install

pip install pyrfcx

Remove real pyrfc from the environment first: both install the import name pyrfc.

Use

from pyrfc import Connection

with Connection(dest="MY_DEST") as conn:
    result = conn.call("STFC_CONNECTION", REQUTEXT="hi")
    print(result["ECHOTEXT"])

dest names a destination in a sapnwrfc.ini file. By default the SDK reads that file from the current directory. You can also pass the connection parameters directly (ashost, sysnr, client, user, passwd, and so on).

What is supported

Area Members
Connection Connection(config=..., **params), open(), close(), reopen(), is_valid(), alive, context manager
Calls call(name, options=..., **params), ping(), cancel()
config keys rstrip, return_import_params, dtime, check_date, check_time, timeout
call options not_requested, timeout
Information version, options, get_connection_attributes()
Descriptions get_function_description(), with FunctionDescription, TypeDescription, RfcFieldType and RfcParameterDirection
Module functions get_nwrfclib_version(), cancel_connection(), set_ini_file_directory(), reload_ini_file(), set_cryptolib_path()
Exceptions The pyrfc classes, with the same names and the same attributes: RFCError, RFCLibError, CommunicationError, LogonError, ABAPApplicationError, ABAPRuntimeError, ExternalAuthorizationError, ExternalApplicationError, ExternalRuntimeError, RFCTypeError

What is not supported

  • Server, Throughput, tRFC, qRFC, bgRFC and WebSocket RFC. This is a client library, so these are out of scope.
  • Not built yet: free(), reset_server_context(), type_desc_get(), type_desc_remove(), func_desc_remove(), set_locale_radix(), the language converters and ConnectionParameters.
  • Connection.handle is not exposed. The Rust core owns the SDK handle.

Tests

Every live test runs against a real ABAP system. The compat suite runs twice on the same SDK: once on pyrfc from pyrfcx and once on real pyrfc 3.4. Both runs must give the same results.

Suite pyrfc 3.4 pyrfc (pyrfcx) pyrfcx C SDK
pyrfc 3.4's own tests, adapted (tests/compat/) 78 78 – –
Added compat tests, each expectation measured on real pyrfc first 56 56 – –
Behaviour facts (unpublished) 168 168 168 168

Performance against real pyrfc

Time was measured on macOS arm64 with SDK 7.50 patch level 15; memory on Windows x64 with patch level 18.

Time. On large tables pyrfc from pyrfcx is faster than pyrfc 3.4 and uses less CPU. On small calls the two are the same: the backend sets the pace. Seconds per call, median of 10 runs in fresh processes:

Case Measure pyrfc 3.4 pyrfc (pyrfcx) pyrfc (pyrfcx) is
RFC_READ_TABLE, 100 000 rows of DD03L Wall time
CPU time
5.79
1.13
5.62
0.99
3 % better
13 % better
100 000 rows of 40 × CHAR(15) Wall time
CPU time
10.98
6.30
9.97
5.27
9 % better
16 % better

Memory. pyrfc from pyrfcx never uses more memory than pyrfc, and its results are smaller: all row dicts share one string object per key. Bytes per table row:

Table shape Measure pyrfc 3.4 pyrfc (pyrfcx) pyrfc (pyrfcx) is
40 × CHAR(15) Peak memory
Size of the result
5 508
5 429
3 606
3 468
35 % better
36 % better
1 × CHAR(512) Peak memory
Size of the result
1 201
614
1 199
561
same
9 % better
Audit log, 30 fields incl. STRING Peak memory
Size of the result
4 993
4 007
4 989
2 333
same
42 % better

Status

  • Version 0.1. The pyrfc API is complete for the client members listed below, and stable.
  • Platforms. Wheels exist for Windows x64, macOS arm64 (macosx_11_0_arm64), and Linux x86_64 and aarch64 (manylinux_2_28). All are cp310-abi3.
  • Client only. Server RFC, tRFC, qRFC and bgRFC are not supported.
  • The native pyrfcx package is not a supported API yet. It ships in the same install because pyrfc runs on it. Its interface may change in any 0.x release and it is not documented here. See "The engine" below.

Requirements

  1. The SAP NW RFC SDK 7.50, patch level 11 or later, for your platform. Patch levels from 5 should also work, but they are untested. The SDK changed its behaviour between patch levels in a few places: docs/sdk-patch-levels.md. The SDK belongs to SAP and is not part of this distribution. Download it from the SAP Support Portal (support.sap.com). You need an S-user.
  2. The environment variable SAPNWRFC_HOME. Set it to the SDK directory (the directory that contains lib/).
  3. CPython 3.10 or later, built for the same architecture as the SDK.
    • Windows: SAP ships the SDK for x64 only. Use an x64 Python, even on an ARM64 machine. An ARM64 Python cannot load the x64 SDK.
    • Linux: the wheel needs glibc 2.28, but the SDK needs more: GLIBCXX_3.4.26 (the libstdc++ of GCC 9) and libuuid.so.1. The wheel runs only where the SDK runs.

With SAPNWRFC_HOME set, nothing else is needed: no PATH or LD_LIBRARY_PATH entry, on any platform. Without it, the SDK is searched by name, and on Windows a stray copy of sapnwrfc.dll can be found whose ICU libraries are not: the first connect then hangs on a hidden "could not open ICU library" dialog instead of failing. Set SAPNWRFC_HOME.

pyrfc 3.4 quirks that the drop-in keeps

A program can depend on a quirk, so pyrfc from pyrfcx reproduces the quirks below.

Case pyrfc 3.4 and the drop-in
A CHAR value ends with a tab or a newline that belongs to the data The character is removed. "AB\t" comes back as "AB".
A STRING value ends with blanks The blanks are removed. "AB " comes back as "AB".
A DATE field is initial Comes back as "". You cannot tell it from an empty value.
A CHAR input is longer than the field The SDK truncates the value. No error.
256 for an INT1 field, 32768 for an INT2 field The value wraps. No error. For INT1 the backend gets 0.
An IntEnum value for an integer field Raises TypeError.
An output parameter is deactivated with not_requested The result contains the parameter with an initial value that the backend never sent.
A scalar parameter is in not_requested and also has a value The value is sent.
str() of an exception The text should start with the name of the return code, such as RFC_INVALID_HANDLE (rc=5): .... It shows the number twice instead: 5 (rc=5): ....
cancel() fails, for example because no call is running cancel() runs the SDK call in a new thread and returns at once. The error is raised in that thread and printed to stderr; the caller cannot catch it.
get_connection_attributes()["dest"] The value is always empty.

Each row is measured on real pyrfc 3.4.

Moving from pyrfc 3.3.1

The drop-in follows pyrfc 3.4, not pyrfc 3.3.1. One difference is visible: the message of a CommunicationError has no trailing newline. pyrfc 3.3.1 keeps the newline that the SDK sends. pyrfc 3.4 right-strips the message, and the drop-in does the same. Code that stores the message stores one character less.

The engine

pyrfcx shares no code with pyrfc. pyrfcx is a new binding of the SAP NW RFC SDK, written in Rust. The pyrfc package is a thin Python layer on top of it that reproduces the pyrfc 3.4 API.

You need no Rust and no compiler to use it. Pre-compiled wheels exist for Windows x64, macOS arm64 and Linux x86_64 and aarch64, for CPython 3.10 and later.

The Rust core loads the SDK at runtime and marshals the character, number, date and time, byte, structure and table types without loss. A call holds the GIL only to build the Python result. The core never closes a handle that the SDK has already freed. The pyrfc package is a facade over the core that reproduces pyrfc's conversions and its quirks.

The native pyrfcx Python API is installed with the facade, but it is not a supported interface yet. It may change in any 0.x release. Use import pyrfc. The native API gets its own documentation when it is ready.

Build from source

You need Rust (stable, 1.95 or later), CPython 3.10 or later and uv. On Windows the Python must be x64. The build does not need the SDK: the package loads it at runtime.

git clone https://github.com/bougebouge/pyrfcx
cd pyrfcx
uv venv --python <path-to-python>
uv pip install "maturin>=1.5,<2"    # or `just sync`, which installs every dev tool

# Build the wheel into target/wheels (on Windows add --target x86_64-pc-windows-msvc)
uv run maturin build --release --out target/wheels

# Install it
uv pip install --find-links target/wheels pyrfcx

just wheels builds the same pyrfcx wheel with the source paths remapped, so the binary holds no path of the build machine; prefer it for a wheel you give to others.

For a development install, use an editable build:

uv run maturin develop --uv     # on Windows add --target x86_64-pc-windows-msvc

The Linux wheels are built in Docker (just linux-wheel <arch>). The tests need a live ABAP system. See CONTRIBUTING.md.

More

License

pyrfcx is licensed under the Apache License, Version 2.0. The SAP NW RFC SDK is not covered by this license. See NOTICE.

SAP, SAP NetWeaver and the SAP NW RFC SDK are trademarks or registered trademarks of SAP SE in Germany and other countries. pyrfc is SAP's Python RFC connector. This project is not affiliated with, endorsed by or sponsored by SAP SE.

Metadata

Release files for pyrfcx 0.2.0

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

Built distributions (wheels)

Table of built distributions (wheels) for pyrfcx 0.2.0
File
pyrfcx-0.2.0-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
pyrfcx-0.2.0-cp310-abi3-manylinux_2_28_x86_64.whl CPython 3.10 abi3 Linux glibc 2.28+ x86-64 Details
pyrfcx-0.2.0-cp310-abi3-manylinux_2_28_aarch64.whl CPython 3.10 abi3 Linux glibc 2.28+ ARM64 Details
pyrfcx-0.2.0-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details

Total release size: 1.6 MB

Release files / pyrfcx-0.2.0-cp310-abi3-win_amd64.whl

Download URL pyrfcx-0.2.0-cp310-abi3-win_amd64.whl
Size 306.9 kB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
015181484806351eb9e507c5954fe8679d70fceee84edff60e6c8d228171eb5c
BLAKE2b-256 checksum
How to use checksums
9ae5e9a416bd9395a11baa8d439ad3d0bd937c22db3a7e0abaa122b06e4dc367
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.15.0

Release files / pyrfcx-0.2.0-cp310-abi3-manylinux_2_28_x86_64.whl

Download URL pyrfcx-0.2.0-cp310-abi3-manylinux_2_28_x86_64.whl
Size 454.0 kB
Tags CPython 3.10 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
442edd5c25ceafeec0ea169de76f4b90da7c728dee8f05b1f9a81f7b743fc8f8
BLAKE2b-256 checksum
How to use checksums
7f60f17e5b5e8e5004cf2524ec7e0a39af2c090f98b182a3fe2c03b1863bd1d9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.15.0

Release files / pyrfcx-0.2.0-cp310-abi3-manylinux_2_28_aarch64.whl

Download URL pyrfcx-0.2.0-cp310-abi3-manylinux_2_28_aarch64.whl
Size 447.2 kB
Tags CPython 3.10 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
ab2300a1df0e230bcd0c8eeef8e2a9f14fea2da7815f855734cd6470c821d544
BLAKE2b-256 checksum
How to use checksums
b58fe980887c1a46f078e028c5523afcbe5c75987b069d9a857737d9c9c6aad4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.15.0

Release files / pyrfcx-0.2.0-cp310-abi3-macosx_11_0_arm64.whl

Download URL pyrfcx-0.2.0-cp310-abi3-macosx_11_0_arm64.whl
Size 412.5 kB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
7245080ebd8a901200eedefac121d420630d79f0e092ced8893b948d5e48ac2f
BLAKE2b-256 checksum
How to use checksums
6ecb6fc8e4b4788a6f8ba026934b7f9164ba872122ea18852ddbfa372f7dcf0d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.15.0

Release history Release notifications | RSS feed

This release

0.2.0 This release

4 release files

0.1.0

4 release files

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