PyRFC - The Python RFC Connector¶
The pyrfc Python package provides Python bindings for SAP NetWeaver RFC Library, for a comfortable way of calling ABAP modules from Python and Python modules from ABAP, via SAP Remote Function Call (RFC) protocol.
It was inspired by Piers Harding’s sapnwrfc package, wrapping the existing SAP NetWeaver RFC Library and rewritten using Cython.
To start using pyrfc
follow the Installation guide.
Documentation¶
Introduction¶
The Python connector (a synonym for the pyrfc
package) wraps the existing SAP NW RFC Library,
often colloquially called SAP C connector or SAP NW RFC SDK. To start using pyrfc
and similar connectors effectively, we highly recommend reading a series of insightful articles
about RFC communication and SAP NW RFC Library, published in the SAP Professional Journal (SPJ),
in 2009, by Ulrich Schmidt and Guangwei Li: Improve communication between your C/C++ applications
and SAP systems with SAP NetWeaver RFC SDK
Part 1: RFC Client Programming,
Part 2: RFC Server Programming,
Part 3: Advanced Topics.
The lecture of these articles and NW RFC SDK Guide (SAP Help)
are recommended as an introduction into RFC communication and programming, while pyrfc
documentation is
focused merely on technical aspects of pyrfc
API.
Example usage¶
In order to call remote enabled ABAP function module, we need to open a connection with valid logon credentials.
from pyrfc import Connection
conn = Connection(user='me', passwd='secret', ashost='10.0.0.1', sysnr='00', client='100')
Using an open connection we can call remote enabled ABAP function modules from Python.
result = conn.call('STFC_CONNECTION', REQUTEXT=u'Hello SAP!')
print result
{u'ECHOTEXT': u'Hello SAP!',
u'RESPTEXT': u'SAP R/3 Rel. 702 Sysid: ABC Date: 20121001 Time: 134524 Logon_Data: 100/ME/E'}
Finally, the connection is closed automatically when the instance is deleted by the garbage collector.
As this may take some time, we may either call the close()
method explicitly
or use the connection as a context manager:
with Connection(user='me', ...) as conn:
conn.call(...)
# connection automatically closed here
Functional coverage¶
The goal of the Python connector development was to provide a package for interacting with SAP ABAP systems on an intuitive and adequate abstract level. Not each and every available function provided by SAP NW RFC Library is therefore wrapped into Python, but classes and methods are implemented, covering the most of the use cases relevant for projects done so far. The drawback of this approach is that fine-grained RFC manipulation is not possible sometimes but coverage can be extended if needed.
In line with this approach, we distinguish between two basic scenarios:
- Client, Python client calls ABAP server
- Server, ABAP client calls Python server
The coverage is as follows:
Client | Server | |
---|---|---|
Standard functionality, e.g. invoking arbitrary RFC | yes | yes (1) |
Transactions (tRFC/qRFC) | yes | no |
Background RFC | yes (2) | no |
RFC Callbacks | no | no |
Secure network connect (SNC) | yes | yes (1) |
Single Sign on (SSO) | no | no |
Note
- Server functionality is currently not working with Python 32bit under Windows.
- Background RFC is currently not working.
- In projecs done so far mainly the Client scenario is used and lot more tested then Server. The Server scenario is therefore considered experimental for now.
Installation¶
Python connector is a wrapper for the SAP NetWeaver RFC Library and you need to obtain and install it first.
If Python is not already installed on your system, you need to download and install Python as well.
After having SAP NW RFC Library and Python installed on your system, you can download and install one of provided
pyrfc
eggs, relevant for your platform and start using pyrfc
.
You can also clone this repository and build pyrfc
from the source code, following Building from source.
SAP NW RFC Library Installation¶
The entry page for SAP NetWeaver RFC library is SAP Service Marketplace (SMP), http://service.sap.com/rfc-library, with detailed instructions how to download, use and compile.
Basically, you should search for SAP NW RFC SDK 7.20
, in Software Downloads
of SAP Software Download Center
on SMP Support Portal, download SAP NW RFC Library adequate for your platform
and Python version combination (see the matrix below) and unpack using SAPCAR
archive utility.

SAPCAR
can be donwloaded from the SMP as well and you should search for SAPCAR 7.20

Which SAP NW RFC Library version is relevant for your platform? Here are platform/Python combinations tested so far:
Platform | Python version | NetWeaver RFC Library (SMP) | Filename (SMP) | Python egg |
---|---|---|---|---|
Windows | Python 2.7 (32bit) | Windows Server on IA32 32bit | NWRFC_20-20004566.SAR |
pyrfc-1.9.3-py2.7-win32.egg |
Windows | Python 2.7 (64bit) | Windows on x64 64bit | NWRFC_20-20004568.SAR |
pyrfc-1.9.3-py2.7-win-amd64.egg |
Linux | Python 2.7 (64bit) | Linux on x86_64 64bit | NWRFC_20-20004565.SAR |
pyrfc-1.9.3-py2.7-linux-x86_64.egg |
Note
- SAP NW RFC Library is fully backwards compatible and it is reccomended using the newest version also for older backend system releases
- SMP search terms and filenames given here will not be regularly updated,
you should always search for current version or filename in
Software Downloads
. - The server functionality is currently not working under Windows 32bit
The Python connector relies on SAP NW RFC Library and must be able to find library files at runtime. Therefore, you might either install the SAP NW RFC Library in the standard library paths of your system or install it in any location and tell the Python connector where to look.
Here are configuration examples for Windows and Linux operating systems.
Windows¶
- Create an directory, e.g.
c:\nwrfcsdk
. - Unpack the SAR archive to it, e.g.
c:\nwrfcsdk\lib
shall exist. - Include the
lib
directory to the library search path on Windows, i.e. extend thePATH
environment variable.
Linux¶
Create the directory, e.g.
/usr/sap/nwrfcsdk
.Unpack the SAR archive to it, e.g.
/usr/sap/nwrfcsdk/lib
shall exist.Include the
lib
directory in the library search path:As
root
, create a file/etc/ld.so.conf.d/nwrfcsdk.conf
and enter the following values:# include nwrfcsdk /usr/sap/nwrfcsdk/lib
As
root
, run the commandldconfig
.
Python Connector Installation¶
Windows¶
If not already installed, you need to install Python first.
First, decide whether you want to go with the 32bit or 64bit version and use standard Windows installers
Python 2.7 (32 bit), http://www.python.org/ftp/python/2.7.6/python-2.7.6.msi
Python 2.7 (64 bit) http://www.python.org/ftp/python/2.7.6/python-2.7.6.amd64.msi
Add Python and Scripts directories to
PATH
environment variable, e.g.set PATH=c:\Python27;c:\Python27\Scripts;%PATH%
Install
easy_install
Use the
distribute
implementation ofeasy_install
by downloading https://bootstrap.pypa.io/ez_setup.py and runningpython ez_setup.py
Note
At this point you may like to install the pip package which extends the functionality of
easy_install
. However,pip
cannot handle binary build distributions, which will be used later.If you are in a internal network that uses a proxy to access resources from the internet, you may encounter connection problems.
Virtual environment (optional)
You may now create an virtual environment and activate it.
Install the Python connector
Open the command prompt with administrator rights, change to the
pyrfc\dist
directory and install adequatepyrfc
egg. You need administrator rights, otherwiseeasy_install
will open a new window and close it after execution – leaving you without the option to see what was done or what was the error.easy_install <egg name>
Please look up the correct egg name depending on your platform and Python version.
Run
python
and typefrom pyrfc import *
. If this finishes silently, without oputput, the installation was successful.
Python on Linux¶
Install Python 2.7 (64bit, usually the default) via your preferred package manager
Install
easy_install
Use the
distribute
implementation ofeasy_install
by downloading https://bootstrap.pypa.io/ez_setup.py and runningpython ez_setup.py
Note
At this point you may like to install the pip package which extends the functionality of
easy_install
. However,pip
cannot handle binary build distributions, which will be used later.If you are in a internal network that uses a proxy to access resources from the internet, you may encounter connection problems.
Virtual environment (optional)
You may now create an virtual environment and activate it.
Install the Python connector:
easy_install <egg name>
Please look up the correct egg name depending on your platform and Python version.
Run
python
, typefrom pyrfc import *
and it it finishes silently, without any output, the installation was successful.
Virtual environments¶
We recommend using a virtual environment for the installation. This allows you to isolate the Python connector installation from your system wide Python installation.
We will now show the example usage for a Windows user that wants to create
a virtual environment in C:\PythonVE\py27-pyrfc
.
- Install
virtualenv
on your system.
C:\>pip virtualenv
- Open a command prompt and change to a directory where you want to create a virtual environment and create a virtual environment.
C:\>cd PythonVE C:\PythonVE\>virtualenv --distribute --no-site-packages py27-sapwnrfc2(Since
virtualenv
version 1.7, the--no-site-packages
option is the default and can be omitted.)
- Activate the environment via
C:\PythonVE\>cd py27-pyrfc C:\PythonVE\py27-pyrfc\>Scripts\activate.bat (py27-pyrfc) C:\PythonVE\py27-pyrfc\>(On Linux use
source bin/activate
.)
- After working on your project, you leave the virtual environment with
(py27-pyrfc) C:\PythonVE\py27-pyrfc\>deactivate C:\PythonVE\py27-pyrfc\>
Problems¶
Behind a Proxy¶
If you are within an internal network that accesses the internet through an HTTP(S) proxy, some of the shell commands will fail with urlopen errors, etc.
Assuming that your HTTP(S) proxy could be accessed via http://proxy:8080
, on Windows
you can communicate this proxy to your shell via:
SET HTTP_PROXY=http://proxy:8080
SET HTTPS_PROXY=http://proxy:8080
or permanently set environment variables.
SAP NW RFC Library Installation¶
ImportError: DLL load failed: The specified module could not be found.
(Windows) This error indicates that the Python connector was not able to find the C connector on your system. Please check, if the
lib
directory of the C connector is in yourPATH
environment variable.ImportError: DLL load failed: %1 is not a valid Win32 application.
(Windows) This error occurs when SAP NW RFC Library 64bit version is installed on a system with 32bit version Python.
Environment variables¶
Windows¶
The environment variable may be set within a command prompt via the set
command, e.g.
set PATH=%PATH%;C:\nwrfcsdk\lib
(extend PATH with the C connector lib)set HTTPS_PROXY=proxy:8080
(setting an proxy for HTTPS communication)
When the command prompt is closed, the environment variable is reset. To achieve a persistent change of the environment variable, do the following (Windows 7):
- Open the Start Menu and type
environment
into the search box. - A window opens in which the user variables are displayed in the upper part and the system variables in the lower part. You may select and edit the desired variable.
- The modified variables are used when a new command prompt is opened.
Client scenario¶
In Client scenario, Python calls remote enabled ABAP function module (FM) [1]
via SAP RFC protocol, as shown in Introduction. To introduce the functionality,
we will start with an three examples, then show some
details of the Connection
, and finally
cover some implementation details.
Examples¶
To create a connection, construct a Connection
object and
pass the credentials that should be used to open a connection to an
SAP backend system.
>>> from pyrfc import Connection
>>> conn = Connection(user='me', passwd='secret', ashost='10.0.0.1', sysnr='00', client='100')
For the examples we usually store the logon information in a config document
(sapnwrfc.cfg) that is read with ConfigParser. Thus, if the logon information
is stored in a dictionary, we may construct a Connection
instance by unpacking the dictionary, e.g.
>>> params = {'user': 'me', 'passwd': 'secret', 'ashost':'10.0.0.1', 'sysnr':'00', 'client':'100'}
>>> conn = Connection(**params)
Example clientStfcStructure.py
¶
Lets do a remote function call with a more complex set of parameters.
A function module knows four types of parameters:
- IMPORT parameters, set by the client.
- EXPORT parameters, set by the server.
- CHANGING parameters, set by the client, can be modified by the server.
- TABLE parameters, set by the client, can be modified by the server.
A simple example of an RFC with different parameter types can be found
in the file clientStfcStructure.py
in the examples/
directory. The FM
STFC_STRUCTURE
uses the IMPORT parameter IMPORTSTRUCT
, copies it
to the EXPORT parameter ECHOSTRUCT
, then modifies it and appends it
to the TABLE parameter RFCTABLE
. Furthermore, it fills the EXPORT parameter
RESPTEXT
with some system/call information.
The parameter IMPORTSTRUCT
is of type RFCTEST
, which contains 12 fields
of different types. We fill these fields with example values (ll. 7-22).
(Note: A comment after each fields tells something about the ABAP datatype.)
imp = dict(
RFCINT1=0x7f, # INT1: Integer value (1 byte)
RFCINT2=0x7ffe, # INT2: Integer value (2 bytes)
RFCINT4=0x7ffffffe, # INT: integer value (4 bytes)
RFCFLOAT=1.23456789, # FLOAT
RFCCHAR1=u'a', # CHAR[1]
RFCCHAR2=u'ij', # CHAR[2]
RFCCHAR4=u'bcde', # CHAR[4]
RFCDATA1=u'k'*50, RFCDATA2=u'l'*50, # CHAR[50] each
RFCTIME=datetime.time(12,34,56), # TIME
RFCDATE=datetime.date(2012,10,03), # DATE
RFCHEX3='\x66\x67\x68' # BYTE[3]: String with 3 hexadecimal values (='fgh')
Afterwards, the FM is invoked via the
call(function_name, **kwargs)
method. It
takes the FM’s name as the first argument and then keyword arguments that
describes the IMPORT, CHANGING, and TABLE parameters.
result = conn.call('STFC_STRUCTURE', IMPORTSTRUCT=imp)
The result contains all EXPORT, CHANGING, and TABLE parameters. It is printed out:
{u'ECHOSTRUCT': {u'RFCCHAR1': u'a',
u'RFCCHAR2': u'ij',
u'RFCCHAR4': u'bcde',
u'RFCDATA1': u'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk',
u'RFCDATA2': u'llllllllllllllllllllllllllllllllllllllllllllllllll',
u'RFCDATE': datetime.date(2012, 10, 3),
u'RFCFLOAT': 1.23456789,
u'RFCHEX3': 'fgh',
u'RFCINT1': 127,
u'RFCINT2': 32766,
u'RFCINT4': 2147483646,
u'RFCTIME': datetime.time(12, 34, 56)},
u'RESPTEXT': u'SAP R/3 Rel. 702 Sysid: E1Q Date: 20121012 Time: 212344',
u'RFCTABLE': [{u'RFCCHAR1': u'X',
u'RFCCHAR2': u'YZ',
u'RFCCHAR4': u'E1Q',
u'RFCDATA1': u'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk',
u'RFCDATA2': u'llllllllllllllllllllllllllllllllllllllllllllllllll',
u'RFCDATE': datetime.date(2012, 10, 12),
u'RFCFLOAT': 2.23456789,
u'RFCHEX3': '\xf1\xf2\xf3',
u'RFCINT1': 128,
u'RFCINT2': 32767,
u'RFCINT4': 2147483647,
u'RFCTIME': datetime.time(21, 23, 44)}]}
There are some points worth mentioning.
- The types of the variables are automatically converted from and to Python objects in an intuitive way.
- Parameters are represented as key-value pairs in a dictionary. For more complex types, the value is a dictionary (for structures) or a list of dictionaries (for tables).
Example clientPrintDescription.py
¶
As you have seen in the previous example, all you need to know for calling a FM is the FM’s name and its parameters – the so called metadata description. However, maybe you don’t know this in advance, so what can you do?
A simple approach is to login to the SAP backend system and investigate the
function module’s description in transaction SE37.
Alternatively, the get_function_description()
method
could be used.
The example script clientPrintDescription.py
retrieves and
prints the metadata description for a given
function module’s name [2]. The get_function_description()
returns a FunctionDescription
object that
contains information about the parameters.
A parameter may have a type description (a TypeDescription
object),
which contains information about the type’s fields.
The scripts iterates over the parameters and fields and prints them out:
Parameters of function: STFC_STRUCTURE
NAME PARAMETER_TYPE DIRECTION NUC_LENGTH UC_LENGTH DECIMALS DEFAULT_VALUE OPTIONAL TYPE_DESCRIPTION PARAMETER_TEXT
IMPORTSTRUCT RFCTYPE_STRUCTURE RFC_IMPORT 144 264 0 False RFCTEST Importing structure
-----------( Structure of RFCTEST (n/uc_length=144/264)--
NAME FIELD_TYPE NUC_LENGTH NUC_OFFSET UC_LENGTH UC_OFFSET DECIMALS TYPE_DESCRIPTION
RFCFLOAT RFCTYPE_FLOAT 8 0 8 0 16 None
RFCCHAR1 RFCTYPE_CHAR 1 8 2 8 0 None
RFCINT2 RFCTYPE_INT2 2 10 2 10 0 None
RFCINT1 RFCTYPE_INT1 1 12 1 12 0 None
RFCCHAR4 RFCTYPE_CHAR 4 13 8 14 0 None
RFCINT4 RFCTYPE_INT 4 20 4 24 0 None
RFCHEX3 RFCTYPE_BYTE 3 24 3 28 0 None
RFCCHAR2 RFCTYPE_CHAR 2 27 4 32 0 None
RFCTIME RFCTYPE_TIME 6 29 12 36 0 None
RFCDATE RFCTYPE_DATE 8 35 16 48 0 None
RFCDATA1 RFCTYPE_CHAR 50 43 100 64 0 None
RFCDATA2 RFCTYPE_CHAR 50 93 100 164 0 None
-----------( Structure of RFCTEST )-----------
----------------------------------------------------------------------------------------------------------------------------------------
RFCTABLE RFCTYPE_TABLE RFC_TABLES 144 264 0 False RFCTEST Importing/exporting table
-----------( Structure of RFCTEST (n/uc_length=144/264)--
[...]
-----------( Structure of RFCTEST )-----------
----------------------------------------------------------------------------------------------------------------------------------------
ECHOSTRUCT RFCTYPE_STRUCTURE RFC_EXPORT 144 264 0 False RFCTEST Exporting structure
-----------( Structure of RFCTEST (n/uc_length=144/264)--
[...]
-----------( Structure of RFCTEST )-----------
----------------------------------------------------------------------------------------------------------------------------------------
RESPTEXT RFCTYPE_CHAR RFC_EXPORT 255 510 0 False None Exporting response message
----------------------------------------------------------------------------------------------------------------------------------------
Once again some remarks:
The
parameter_type
andfield_type
are not the ABAP types (that were given as a comment in the first example), but the type names given by the C connector. For more details on the type conversion, see the technical details.Most of the information presented here is not relevant for client usage. The important values are:
FunctionDescription.parameters
name
,parameter_type
,direction
,nuc_length
(in case of fixed length strings or numeric strings),decimals
(in case of decimal types –RFCTYPE_BCD
), andoptional
.TypeDescription.fields
name
,field_type
,nuc_length
(in case of fixed length strings or numeric strings), anddecimals
(in case of decimal types –RFCTYPE_BCD
).
Later, in the Server scenario usage, the classes
FunctionDescription
andTypeDescription
will be used again when installing a function on a Python server.
Errors¶
If something goes wrong while working with the RFC functionality, e.g. invoking a function module that does not exist in the backend, an error is raised:
>>> python clientPrintDescription.py STFC_STRUCTURES
... An error occurred.
... [...]
... pyrfc._exception.ABAPApplicationError: Error 5: [FU_NOT_FOUND] ID:FL Type:E Number:046 STFC_STRUCTURES ABAP: FL E 046 STFC_STRUCTURES
For further description see Errors.
Example clientIDocUnit.py¶
Warning
The background protocol (bgRFC) is not working in the current version. Please use only tRFC/qRFC protocols.
Certain operations, e.g. sending IDocs, are not possible with the RFC protocol.
Rather, a protocol with transactional guarantees has to be used.
The first transactional protocols were tRFC (transactional RFC)
and qRFC (queued RFC). Afterwards, bgRFC (background RFC) were introduced.
All these protocols have in common that they group one or more FM invocations
as one logical unit of work (LUW). Consequently, a Connection
object offers various methods to work with such units.
Working with units is as follows:
- Initialize a unit by using
initialize_unit()
. The method returns a unit descriptor, which is used later on. When initializing the unit, decide whether to use the bgRFC protocol (default) or the tRFC or qRFC protocol by settingbackground=False
. - The next step is to create the unit in the backend system,
prepare the invocation of one or more RFC in it and submit the unit to the
backend. All this functionality is provided by
fill_and_submit_unit()
. The method takes two required parameters. The first one is a unit descriptor as returned byinitialize_unit()
. The second one is a list of RFC descriptions that should be executed in the unit. A RFC descriptions consists of a tuple with the name of the FM as the first element and a dictionary describing the function container as the second element. - If
fill_and_submit_unit()
ended successfully, i.e. without raising an exception, the unit should be confirmed byconfirm_unit()
. In case there is a problem with the unit, it can be deleted in the backend system by callingdestroy_unit()
.
The current state of a unit can be – in case of units using the bgRFC protocol –
retrieved by get_unit_state()
.
The example script clientIDocUnit.py
provides examples for
sending iDocs. The script was inspired by iDocClient.c
of
Schmidt and Li (2009c, pp. 2ff), but omits the implementation
of client side features that assure atomic execution (see also next section).
Note
Use transaction WE05
to see the IDocs recorded in the SAP backend.
Note
In case you are using queued units (qRFC), use transaction SMQR
to
register a new queue. In transaction SMQ2
(qRFC monitor) you see the
incoming calls.
Note that it is possible to send the unit to a non-registered queue name.
It will be held with status ready
in the monitor until it is deleted or
the queue registered. For further information, see qRFC Administration.
Assuring atomic execution¶
In order to assure that the unit is executed exactly once, it is of great importance that the end system on the client side initiates the confirmation. Citing Schmidt and Le (sapnwrfc.h, l. 1361ff) with modifications:
After [fill_and_submit_unit()] returned successfully, you should use this function to cleanupthe status information for this unit on backend side. However, be careful: if you havea three-tier architecture, don’t bundle Submit and Confirm into one single logical step.Otherwise you run the risk, that the middle tier (the NW RFC lib) successfully executesboth, the Submit and the Confirm, but on the way back to the first tier an error occursand the first tier can not be sure that the unit was really executed in the backend andtherefore decides to re-execute it. This will now result in a duplicate execution in thebackend, because the Confirm step in the first try has already deleted the UID in thebackend, and consequently the backend is no longer protected against re-execution of thisUID. In a three-tier architecture, the first tier should trigger both steps separately:first the Submit, and after it knows that the Submit was successful, the Confirm.Also in case the Confirm runs into an error, [...] try the Confirm again at a later point [.]
Further details to this issue can be found in Schmidt and Li (2009c, pp. 4-5).
Configuration of a connection¶
Upon construction, a Connection
object may be configured
in various ways by passing a config
parameter.
>>> conn = Connection(config = {'keyword': value, ...}, **params)
The following keywords for the config dictionary are possible:
rstrip
¶
ABAP allows two different ways to store strings: A fixed length string type C
and a dynamic length string type STRING.
Strings of type C are padded with blanks, if the content is shorter than the
predefined length. In order to unify the connector’s behavior regarding strings,
the rstrip
option was introduced. If set to True
, all strings are
right-stripped before being returned by an RFC call.
Default: True
return_import_params
¶
Usually, you do not need the IMPORT parameters in the result of
Connection.call()
. If return_import_params
is set to False
,
parameters of type IMPORT are filtered out.
Default: False
Note
All the parameters are public object attributes, i.e. they can be modified after the object’s construction.
Selected Connection
methods¶
Besides the mentioned methods in the examples, the Connection
offers
some basic methods for working with a connection:
Connection.ping |
|
Connection.reset_server_context |
|
Connection.get_connection_attributes |
|
Connection.close |
Technical details¶
This section describes the Data types and the Data transmission.
Data types¶
A remote function call executes ABAP code, which works with parameters that have an ABAP data type. Hence, when you look at the metadata description you will find ABAP data types for the parameters.
The Python connector does not provide ABAP data types to be instantiated and used within Python code, but rather converts between ABAP data types and Python built-in types.
Type Category | ABAP | Meaning | RFC | Python | Remark |
---|---|---|---|---|---|
numeric | I | Integer (whole number) | INT | int | Internal 1 and 2 byte integers (INT1, INT2) are also mapped to int |
numeric | F | Floating point number | FLOAT | float | |
numeric | P | Packed number / BCD number | BCD | Decimal | |
character | C | Text field (alphanumeric characters) | CHAR | unicode | |
character | D | Date field (Format: YYYYMMDD) | DATE | datetime.date | |
character | T | Time field (Format: HHMMSS) | TIME | datetime.time | |
character | N | Numeric text field (numeric characters) | NUM | unicode | |
hexadecimal | X | Hexadecimal field | BYTE | str [bytes] | |
variable length | STRING | Dynamic length string | STRING | unicode | |
variable length | XSTRING | Dynamic length hexadecimal string | BYTE | str [bytes] |
Further details on predefined ABAP types are available online.
The Python representation of a parameter is a simple key-value pair, where the key is the name of the parameter and the value is the value of the parameter in the corresponding Python type. Beside the mentioned types, there are tables and structures:
- A structure is represented in Python by a dictionary, with the structure fields’ names as dictionary keys.
- A table is represented in Python by a list of dictionaries.
For an example see Example clientStfcStructure.py.
Data transmission¶
The data transmission in the C connector takes place as follows: If you want to invoke an RFC, a function container is constructed from the metadata description of the RFC. The function container is a memory structure to which the parameters are written. Then the RFC is invoked and the function container is passed to the backend system. The backend system now executes the RFC on the given function container, i.e. it reads some values from the function container and writes other values to it. Finally, the function container is passed back to the C connector.
This has some important consequences:
- There is no technical distinction between input and output values.
- In the metadata description, each parameter is classified as IMPORT, EXPORT, CHANGING, and TABLES. Hence, there is a convention regarding which parameters are set when the RFC is invoked and which parameters are filled or changed after the RFC’s execution.
- It is possible, though not good practice, to set the output values (i.e. parameter of type EXPORT) when invoking an RFC. Similarly, it is possible that an RFC will modify the input values (parameters of type IMPORT). However, a well written RFC will not manipulate the input values and initialize the output values to a default value.
Footnotes
[1] | To be invoked externally, the function module needs to be remote-enabled. For the sake of readability, we will use the shorter term (“FM”) throughout the text. |
[2] | This example was inspired by the printDescription.c of
Schmidt and Li (2009a, pp. 3ff). |
Server scenario¶
Server usage refers to a situation, in which a Python script serves RFC requests that are sent by an SAP backend system.
To illustrate the usage, we will first show an Example serverStfcConnection.py, then describe some basic aspects of the Server and finally cover some Advanced topics.
Note
For this section, we assume previous knowledge from the Client scenario section. Furthermore, the server related article by Schmidt and Li (2009b) is highly recommended.
Warning
Server functionality is currently not working with Python 32bit under Windows.
Example serverStfcConnection.py
¶
Creating a Python RFC server consists basically of two parts:
- A
Server
object that stores metadata about the functions that it will serve, and that later registers at a gateway. - For each served function, a callback function (or: implementing function) has to be provided.
A simple example for a server can be found
in the file serverStfcConnection.py
in the examples/
directory.
This server offers a function with the same metadata as STFC_CONNECTION
,
but will return a slightly modified version as the usual ABAP implementation.
The metadata for STFC_CONNECTION
consists of
- one IMPORT parameter –
REQUTEXT
– and - two EXPORT parameters –
ECHOTEXT
(usually a copy ofREQUTEXT
) andRESPTEXT
(usually some connection/system details).
STFC_CONNECTION
callback function¶
Lets look at our callback function (ll. 9-14), that implements the server logic:
config = ConfigParser()
config.read('sapnwrfc.cfg')
# Callback function
def my_stfc_connection(request_context, REQUTEXT=""):
return {
The callback function takes two parameters. The first one, request_context
contains call-specific information and is obligatory for any callback function.
Afterwards, the parameters depend on the function’s metadata description.
In our case, there is one IMPORT parameter that is expected by the callback
function.
The callback function fills the value for the two EXPORT parameters and returns them in a dictionary.
STFC_CONNECTION
Server¶
The Server
class offers server related functionality.
In the example, its usage is found in lines 23-27.
params_connection = config._sections['connection']
conn = Connection(**params_connection)
func_desc_stfc_connection = conn.get_function_description("STFC_CONNECTION")
# Instantiate server with gateway information for registering, and
- First, a
Server
object is created and gateway parameters are passed. - Second, a function is installed via
install_function()
. The parameters are aFunctionDescription
object and a callback function. - Finally, the server serves requests by invoking the
serve()
method.
A remark regarding the second point: The function description for our callback function is retrieved from an SAP system in lines 17-20.
'RESPTEXT': u"Python server here. Connection attributes are: "
u"User '{user}' from system '{sysId}', client '{client}', "
u"host '{partnerHost}'".format(**request_context['connection_attributes'])
}
Retrieving functions descriptions in such a way is convenient for various reasons (cf. Schmidt and Li (2009b, p. 2)). However, hard coding of function descriptions is possible (cf. Example serverFunctionDescription.py).
Registering the server¶
Registering the server needs some preparation in the SAP backend.
Configuration of RFC connections is handled in transaction SM59
.
Create a new RFC destination (e.g. PYTHON_SVR_DEST
) of type T
and
choose under technical settings:
- Activation type: Registered Server Program
- Registered Server Program: Program ID <your program ID>
The program ID is used when instantiating a Server object.
Invoking the server¶
A simple approach to invoke our server is to
- log on to an SAP backend system,
- use transaction
SE37
, - test/execute the function module
STFC_CONNECTION
, and - set
RFC target sys.
to the RFC destination of the server (e.g.PYTHON_SVR_DEST
).
Server¶
For server usage, the Python connector offers the class Server
.
An object is instantiated with gateway parameters. The server will register
at this gateway before serving requests.
Gateway parameters are:
GWHOST
- The name of the gateway host
GWSERV
- The name of the gateway server
PROGRAM_ID
- The name under which the Python connector will register at the gateway. This
corresponds to an RFC destination in transaction
SM59
of type “T” in registration mode. TRACE
- Sets the trace level, cf. the documentation of
RfcSetTraceLevel
insapnwrfc.h
of the C connector. SAPROUTER
- An SAP router string
Furthermore, the server accepts a config
parameter.
Config¶
Upon construction, a Server
object may be configured
in various ways by passing a config
parameter.
rstrip
¶
ABAP allows two different ways to store strings: A fixed length string type C
and a dynamic length string type STRING.
Strings of type C are padded with blanks, if the content is shorter than the
predefined length. In order to unify the connectors behavior regarding strings,
the rstrip
option was introduced. If set to True
, all strings are right
stripped before being passed to the callback function.
Default: True
Server functions¶
The Server.install_function()
installs a function in the server. It
expects two parameters: a FunctionDescription
object for the metadata
description and a callback function that implements the server logic.
The callback function will be called if the gateway receives an RFC call for
the given FunctionDescription
and if the server object is serving
requests (Server.serve()
).
In this case, the callback function is called with the following parameters:
request_context
A dictionary with the following key:
connection_attributes
- A dictionary with connection attributes of the client. The keys are the
same as returned by
Connection.get_connection_attributes()
, excludingalive
andactive_unit
. As done byConnection.get_connection_attributes()
, the values are right stripped strings. These connection attributes may be used for authorization checks.
For a future release, information about active parameters will be given here.
<PARAMETERS>
- All IMPORT, CHANGING, and TABLE parameters of the
FunctionDescription
.
Advanced topics¶
Raising exceptions¶
An external server program is allowed to throw errors as a usual ABAP function module. To do so, a certain type of exception is raised.
Error type | Corresponds to ABAP statement | In Python triggered via | Arguments to pass | Effect on connection | Effect in the back end (ABAP) |
---|---|---|---|---|---|
ABAP exception | RAISE <exception key> | raise ABAPApplicationError(...) | key | Remains open | SY-SUBRC is set corresponding to the exception key in the EXCEPTIONS clause. |
ABAP exception with details | MESSAGE ... RAISING <exception key> | raise ABAPApplicationError(...) | key, msg_type, msg_class, msg_number, msg_v1-v4 | Remains open | As above. The following fields are filled: SY-MSGTY, SY-MSGID, SY-MSGNO, and SY-MSGV1-V4. |
ABAP message | MESSAGE ... | raise ABAPRuntimeError(...) | msg_type, msg_class, msg_number, msg_v1-v4 | Is closed | SY-SUBRC is set corresponding to the SYSTEM_FAILURE key in the EXCEPTIONS clause and the SY-MSG fields are filled as above. |
System failure | raise ExternalRuntimeError(...) | message | Is closed | SY-SUBRC is set corresponding to the SYSTEM_FAILURE key in the EXCEPTIONS clause and the parameter specified in the MESSAGE addition is filled. |
Other exceptions are not permitted. For further details on error raising cf. Schmidt and Li (2009b, pp. 6ff).
Note that the arguments have a maximum length. If a longer string is passed, only the first valid number of characters will be used.
- key: 128 chars
- message: 512 chars
- msg_type: 1 char
- msg_class: 20 chars
- msg_number: 3 chars
- msg_v1-v4: 50 chars each
Authorization¶
At the current state of the Python connector, an authorization check has to
be implemented in the callback function by evaluating the connection attributes
found in request_context['connection_attributes']
(cf. Server functions).
Hard-coded function descriptions¶
In some cases, it is not possible to retrieve the metadata from an SAP backend
system (cf. Schmidt and Li (2009c, pp. 9ff)). For these situations,
objects of FunctionDescription
and
TypeDescription
can be hard-coded.
The required methods are
FunctionDescription.add_parameter |
|
TypeDescription.add_field |
Example serverFunctionDescription.py¶
Similar to the example hardCodedServer.c
of the C connector, in the file
serverFunctionDescription.py
in the examples/
directory,
a function description – and included type descriptions – are constructed
manually.
In line 3-15 we define a TypeDescription
object
consisting of three fields:
animals = TypeDescription("ANIMALS", nuc_length=20, uc_length=28)
animals.add_field(name=u'LION', field_type='RFCTYPE_CHAR',
nuc_length=5, uc_length=10,
nuc_offset=0, uc_offset=0
)
animals.add_field(name=u'ELEPHANT', field_type='RFCTYPE_FLOAT', decimals=16,
nuc_length=8, uc_length=8,
nuc_offset=8, uc_offset=16,
)
animals.add_field(name=u'ZEBRA', field_type='RFCTYPE_INT',
nuc_length=4, uc_length=4,
nuc_offset=16, uc_offset=24
)
Afterwards, a FunctionDescription
object is created and
several fields are added.
func_desc = FunctionDescription("I_DONT_EXIST")
func_desc.add_parameter(name=u'DOC', field_type='RFCTYPE_INT',
direction='RFC_IMPORT',
nuc_length=4,
uc_length=4
)
func_desc.add_parameter(name=u'CAT', field_type='RFCTYPE_CHAR',
direction='RFC_IMPORT',
nuc_length=5,
uc_length=10
)
func_desc.add_parameter(name=u'ZOO', field_type='RFCTYPE_STRUCTURE',
direction='RFC_IMPORT',
nuc_length=20,
uc_length=28,
type_description=animals
)
func_desc.add_parameter(name=u'BIRD', field_type='RFCTYPE_FLOAT',
direction='RFC_IMPORT',
nuc_length=8,
uc_length=8,
decimals=16
)
func_desc.add_parameter(name=u'COW', field_type='RFCTYPE_CHAR',
direction='RFC_EXPORT',
nuc_length=3,
uc_length=6
)
func_desc.add_parameter(name=u'STABLE', field_type='RFCTYPE_STRUCTURE',
direction='RFC_EXPORT',
nuc_length=20,
uc_length=28,
type_description=animals
)
func_desc.add_parameter(name=u'HORSE', field_type='RFCTYPE_INT',
direction='RFC_EXPORT',
nuc_length=4,
uc_length=4
)
Security¶
Plain RFC connections are mainly used for prototyping, while in production secure connections are required. For more information on RFC security see:
- Security on SAP Service Marketplace
- RFC Security Best Practices on SAP SCN
- Secure Network Communication (SNC) - SAP Help
- SNC User Guide
SAP NW RFC Library supports plain and secure connection with following authentication methods:
NW ABAP servers support in addition:
- SAP logon tickets
- Security Assertion Markup Language (SAML)
Assuming you are familiar with abovementioned concepts and have ABAP backend system configured for SNC communication, here you may find connection strings examples, for testing plain and secure RFC connections, with various authentication methods.
Authentication¶
Plain with user / password¶
The simplest and least secure form of the user authentication.
ABAP_SYSTEM = {
'user': 'demo',
'passwd': 'welcome',
'name': 'I64',
'client': '800',
'ashost': '10.0.0.1',
'sysnr': '00',
'saprouter': SAPROUTER,
'trace': '3'
}
c = get_connection(ABAP_SYSTEM) # plain
SNC with User PSE¶
User PSE is used for opening the SNC connection and the same user is used for the authentication (logon) in NW ABAP backend. Generally not recomended, see SAP Note 1028503 - SNC-secured RFC connection: Logon ticket is ignored
Prerequisites
- SNC name must be configured for the ABAP user in NW ABAP system, using transaction SU01

- SAP Single Sign On must be configured on a client and the user must be logged in on a client.
ABAP_SYSTEM = {
'snc_partnername': 'p:CN=I64, O=SAP-AG, C=DE',
'snc_lib': 'C:\\Program Files (x86)\\SECUDE\\OfficeSecurity\\secude.dll',
'name': 'I64',
'client': '800',
'ashost': '10.0.0.1',
'sysnr': '00',
'saprouter': SAPROUTER,
'trace': '3'
}
c = get_connection(ABAP_SYSTEM)
In this example the SNC_LIB key contains the path to security library (SAP cryptographic library or 3rd party product). Alternatively, the SNC_LIB can be set as the environment variable, in which case it does not have to be provided as a parameter for opening SNC connection.
SNC with X509¶
The client system PSE is used for opening SNC connection and forwarding user X509 certificate to NW ABAP backend system, for authentication and logon.
Prerequisites
- The user does not have to be logged into the client system, neither the Single Sign On must be configured on a client
- The trusted relationship must be established between the NW ABAP backend and the client system.
- The client system must be registered in the NW ABAP backend Access Control List (ACL), using transaction SNC0
- Keystores are generated on a client system, using SAP cryptography tool SAPGENPSE and the environment variable SECUDIR points to the folder with generated keystores


- User X509 certificate must be mapped to ABAP NW backend user, using transaction EXTID_DN


The same connection parameters as in a previous example, with X509 certificate added.
ABAP_SYSTEM = {
'snc_partnername': 'p:CN=I64, O=SAP-AG, C=DE',
'snc_lib': 'C:\\Program Files (x86)\\SECUDE\\OfficeSecurity\\secude.dll',
'x509cert': 'MIIDJjCCAtCgAwIBAgIBNzA ... NgalgcTJf3iUjZ1e5Iv5PLKO',
'name': 'I64',
'client': '800',
'ashost': '10.0.0.1',
'sysnr': '00',
'saprouter': SAPROUTER,
'trace': '3'
}
c = get_connection(ABAP_SYSTEM)
See SAP Help for more information.
Building from source¶
SAP NW RFC Library shall be installed as described in the Installation. Instead of downloading and installing precompiled egg, you
need to prepare the toolchain and clone the pyrfc
repository, so that you can build
the distribution release code and documentation.
Toolchain preparation¶
Linux platform¶
- Install Python
- Install
easy_install
as described in pyrfc installation - Install SAP NW RFC Library
- To get any software from the Git source control system the Git client is required as well, use whatever your distribution has
- Install Cython. Versions tested so far are 0.17.2, 0.19.0 and 0.20.0, other are expected to work as well.
- The system must contain a
gcc
compiler as well as development header and library files as provided by your distribution.
Windows platform¶
- Install Python
- Install
easy_install
as described in pyrfc installation - Install SAP NW RFC Library
- To get any software from the Git source control system the Git client is required as well. Download and install from http://code.google.com/p/msysgit/downloads/list?can=3. During installation specify that Git runs out of the Bash shell as you may need that shell later on.
- Install Cython, using Windows installer, see also http://wiki.cython.org/64BitCythonExtensionsOnWindows
- Download and install the compiler toolchain, tested on Windows 7 32 and 64 bit platforms
Building the code¶
To build eggs for different Python versions, install these versions on your system and create a virtual environment for each of these versions, for example:
virtualenv --python=<PATH e.g. c:\Python27\python.exe OR /usr/bin/python2.7> ...
Otherwise, follow the example below.
Linux platform¶
Clone the repository:
git clone https://github.com/SAP/PyRFC
Edit setup.py
and set the CYTHON_VERSION
Build the distribution
python setup.py clean --all
python setup.py bdist_egg
The result is found in the dist/
directory. The process has to be done on all platforms
for which we provide eggs.
Windows platform¶
Open the GIT Bash
shell and clone the repository.
git clone https://github.com/SAP/PyRFC
Open the CMD Shell
from Microsoft Windows SDK 7.0
and change to cloned pyrfc
folder.
Edit setup.py
and set the CYTHON_VERSION
Set env variables for the release, use /x64 for 64 bit and /x86 for 32 bit:
set DISTUTILS_USE_SDK=1
setenv /x64 /release
Build the distribution:
python setup.py clean --all
python setup.py bdist_egg
Check the pyrfc\dist
folder for a new created egg.
Virtual Environments¶
You may have buth 32bit and 64bit versions of Python installed on your
system and use virtual environments. This is basically possible (e.g. installing
the 32bit version on 64 bit system in C:\Python27_32\
, but beware of modifying
the PATH variable.
However, the PATH variable is modified when using a virtual environment, therefore
modify the Scripts/activate.bat
file with:
set SAPNWRFC_HOME=C:\nwrfcsdk_x86
set PATH=C:\nwrfcsdk_x86\lib\;%PATH%
set PATH=%VIRTUAL_ENV%\Scripts;%PATH%
This assures that specific SAP NW RFC Library is used (e.g. 32bit in this example). This is not required for building the distribution, but rather for importing the Python connector.
The build process remains the same, only before building the distribution, you need to
activate the virtual environment and assure that library paths are correct in setup.py
.
Python 3¶
Prerequisites for building on Python 3, tested on Linux Mint and Ubuntu
sudo apt-get install python3-setuptools python3-dev python-configparser
sudo easy_install3 pip
sudo pip3 install cython sphinx ipython
Building the documentation¶
Ensure that the lib directory of the SAP NW RFC library is in your PATH environment.
Change into the doc
directory and type:
make clean
make html
The result is found in _build/html
and for other options call make
.
- If you get an error ‘sphinx-build’ is not recognized as an internal or external command, operable program or batch file on calling
make html
, installsphinx
- If you have DLL import errors (Windows), check the lib directory of the SAP NW RFC Library PATH env variable.
The docu is hosted on GitHub Pages, a propietary solution where a git branch gh-pages
is created
as an orphan and the output of the documentation build process (_build/html
) is stored in that branch.
GitHub then serves these files under a special /pages/
url.
To update GitHub Pages, copy everyhing under _build/html
and overwrite the existing files in the gh-pages
branch root.
cp _build/html ~/tmp
git checkout gh-pages
rm -Rf *.html *.js *.egg build doc _* pyrfc* *.inv .buildinfo
cp -R ~/tmp/_build/html/. .
Note
An additional file .nojekyll is placed in gh-pages
to disable the default GitHub processing which breaks sphinx style folders with leading underscores.
gh-pages
updates are a bit inconvenien, check if this answer helps http://stackoverflow.com/questions/4750520/git-branch-gh-pages
Remarks¶
RFC call results differ from expected¶
The response when invoking ABAP function module directly via transaction SE37 may be different from the response when called via Python connector. Typically leading zeros are not shown in SE37 but sent to Python when remote FM is called from Python.
This is surely a bug and in general there are few possible causes:
the pyrfc
package, the SAP NW RFC Library, or the function
module itself. Bugs in SAP NW RFC Library are unlikely, in pyrfc
less likely and
the cause is usually the implementation of the ABAP FM, not respecting technical restriction
described here.
Conversion (“ALPHA”) exists are triggered in SAP GUI and in SE37 but not when the ABAP FM is called via SAP RFC protocol, therefore the rectifying logic shall be implemented in the FM. The behaviour can be also caised by different authorization levels, when ABAP FM is invoked locally or remotely, via SAP RFC protocol.
Please try to assure that RFC is working (e.g. testing with the C connector), before reporting the problem.
Multiple threads¶
If you work with a multiple thread environment, assure that each thread has
its own Connection
object. The reason is that during the RFC calls,
the Python global interpreter lock (GIL) is released.
Open, valid, and alive connections¶
A connection may be closed by the client (e.g. via Connection.close()
) or
by the server (e.g. if an ABAP message is raised). The connection object
maintains a object variable alive
to record the actual state.
However, the variable is of internal use only, as the connection object
will try to reopen the connection, if needed.
This leads to the – seemingly strange – situation that an explicitly closed
connection will allow you to call, e.g. Connection.ping()
.
Implementation remark: It is not possible to query the actual state of the
connection in a reliable manner. Although SAP NW RFC Library offers the function
RfcIsConnectionHandleValid()
, it will only return False if the connection
was closed by the client, not if it was closed from the server side. Therefore,
an explicit object variable is kept.
Bibliography¶
Schmidt and Li (2009a)¶
Improve communication between your C/C++ applications and SAP systems with SAP NetWeaver RFC SDK - Part 1: RFC Client Programming, SAP Professional Journal, pp 1-16 (originally published in November 2007)
Schmidt and Li (2009b)¶
Improve communication between your C/C++ applications and SAP systems with SAP NetWeaver RFC SDK - - Part 2: RFC Server Programming, SAP Professional Journal, pp 1-13 (originally published in January/February 2008)
Schmidt and Li (2009c)¶
Improve communication between your C/C++ applications and SAP systems with SAP NetWeaver RFC SDK - Part 3: Advanced Topics, SAP Professional Journal, pp 1-18 (originally published in March 2008)
API documentation¶
pyrfc
¶
The pyrfc
package.
Connection¶
Server¶
FunctionDescription¶
Note
Actually, the FunctionDescription class does not support exceptions.
TypeDescription¶
Errors¶
If a problem occurs in the Python connector or in an underlying component (e.g. C connector, SAP system, ABAP code, ...), an exception is raised. The class of the exception indicates where the problem occurred.
RFCError
: This error is raised, if a problem occurred in the Python connector.RFCLibError
: This error is raised, if a problem occurred in the C connector.- All other errors represent errors with the RFC call to the SAP backend
system. For these errors, the errorInfo struct of the C connector is wrapped,
e.g. for a given exception
e
, the error code is available ine.code
. The class of the error depends on the group of the error.

Error types, codes, groups, and classes¶
Schmidt and Li (2009a) describe four possible error types on the basis of the return code (i.e. error code) of a RFM invocation:
- ABAP exception,
- system failure,
- ABAP messages, and
- communication failure.
However, there are in total roughly 30 possible return codes that indicate some kind of error. As each error information struct provides an error group information with seven possible groups, which was taken as the basis for the exception classes.
The following table should facilitate the matching between the different error representations.
type (SPJ) | code [numeric] (C) | group (C) | class (Python) |
---|---|---|---|
ABAP exception | RFC_ABAP_EXCEPTION [5] | ABAP_APPLICATION_FAILURE | ABAPApplicationError |
system failure | RFC_ABAP_RUNTIME_FAILURE [3] | ABAP_RUNTIME_FAILURE | ABAPRuntimeError |
ABAP message | RFC_ABAP_MESSAGE [4] | ABAP_RUNTIME_FAILURE | ABAPRuntimeError |
communication failure | RFC_COMMUNICATION_FAILURE [1] | COMMUNICATION_FAILURE | CommunicationError |
RFC_LOGON_FAILURE [2] | LOGON_FAILURE | LogonError |
Change log¶
Change log¶
1.9.4 (Development) - RfcGetVersion API added - More docu - Unit tests
1.9.3 (2014-01-26)¶
- Fixed Date wrap bug (reported by Flavio Marinone)
- Documentation rework
1.9.2 (2012-11-26)¶
- Fixed BCD wrap bug (reported by Thomas Marcon)
1.9.1 (2012-10-02)¶
- Added server usage
- Server class (wraps server related activities)
- FunctionDescription and TypeDescription as classes for improved metadata handling.
- Added support for transactional, queued, and background RFC (tRFC, qRFC, bgRFC) for client usage.
- Renamed exceptions in accordance with PEP08:
- Exception names changed to Error (e.g. ExternalRuntimeException renamed to ExternalRuntimeError).
- Rfc now uppercase, e.g. RFCLibError.
- Abap now uppercase, e.g. ABAPRuntimeError.
- Connection class
- removed __init__ optional parameter strip, added config dictionary as optional parameter.
- renamed connectionInfo to get_connection_attributes()
- renamed resetServerContext to reset_server_context()
- RFCTYPE_BCD fields are now converted to Decimal object (wrap). For filling, you may pass either Decimal objects or floats.
1.9 (2012-09-14)¶
- Restructured exceptions:
- All exceptions are now directly available in the pyrfc package (e.g. from pyrfc import LogonException)
- RfclibException renamed to RfcLibException
- All used exceptions (corresponding to RFC error group classes) inherit now from RfcLibException (implication for LogonException, AbapRuntimeException, AbapApplicationException)
- Constructor for RfcLibException changed (first argument is now message), allowing to raise exceptions manually with only one string value
- AbapException deleted.
- Added external exceptions (ExternalRuntimeException, ExternalApplicationException, ExternalAuthorizationException)
- restructured and added tests (MRFC and STFC function groups).
- fixed bugfix implications from rev. 1.8.2. (LogonException does not have code fields now)
- Added examples (sample/): printDescription.py
1.8.2 (2012-04-05)¶
- bugfix: LogonException now inherits from RfcException instead of RfcLibException so it only needs one message argument.
1.8.1 (2012-02-27)¶
- (bugfix in removed module)
1.8 (2012-02-07)¶
- added strip parameter in Connection to rstrip whitespaces in rfc results
- added resetServerContext
- fixed bug when dealing with xstring results
- added __bool__ for easy check if connections is alive
- release GIL for RfcInvoke and RfcOpenConnection
1.7 (2011-12-23)¶
- wrapped fillVariable into try..except block to enrich exception information
- Added _pyrfc.connectionInfo (sapnwrfc.RfcGetConnectionAttributes)
1.6 (2011-12-12)¶
- added bcd conversion
- added performance test
- added setup.py test suite
1.5 (2011-12-05)¶
- first buildout configuration that works on Linux and Windows
- rename the C extension to
_pyrfc
and importing it at the root of a new “real” Python packagepyrfc
. This is fully backwards compatible and allows splitting the single module into a C-only part and separate Python modules for bettr maintainability. - move pure Python code from the Cython extension module into separate Python modules for maintainability
1.4 (2011-11-25)¶
- start on package documentation
- re-added support for zero dates
1.3 (2011-11-22)¶
- fixed various buffer length issues
1.2 (2011-11-18)¶
- malloc’ed buffer, never too small
- type-specific RFCGetters
1.1 (2011-11-16)¶
- your buffer was too small
1.0 (2011-11-11)¶
- first egg release