Skip to main content

A simple library to interact with Salesforce REST API using OAuth 2.0 Client Credentials Flow.

Project description

SalesforceRESTAPI

A simple Python library to interact with the Salesforce REST API using OAuth 2.0 Client Credentials Flow.

Features

  • Authenticate with Salesforce using OAuth 2.0 Client Credentials
  • Basic CRUD operations (create, read, update, delete) for Salesforce objects
  • Bulk API 2.0 support for inserting large datasets
  • SOQL query support
  • Apex script execution via Tooling API
  • Record verification utilities
  • HTTP status code tracking for all API requests

Installation

pip install SalesforceRESTAPI

Usage

Note: As of version 0.1.3, authentication state (instance_url, access_token, headers) is stored as class variables. You must call SalesforceRESTAPI.authenticate(...) before using any instance methods. All instances share the same authentication state.

from SalesforceRESTAPI import SalesforceRESTAPI

# Authenticate (call this once before using any instance methods)
SalesforceRESTAPI.authenticate(client_id='YOUR_CLIENT_ID', client_secret='YOUR_CLIENT_SECRET', login_url='https://login.salesforce.com')

# Now you can use instance methods
sf = SalesforceRESTAPI()

# Create a record
account_id = sf.create_record('Account', Name='Test Account', Industry='Technology')

# Get a record
account = sf.get_record('Account', account_id)

# Update a record
sf.update_record('Account', account_id, Name='Updated Name')

# Delete a record
sf.delete_record('Account', account_id)

# Run a SOQL query
results = sf.queryRecords('SELECT Id, Name FROM Account')

# Execute anonymous Apex
apex_result = sf.execute_apex('System.debug("Hello World");')

# Bulk insert records (for large datasets)
records = [
    {'Subject': 'Test Case 1', 'Status': 'New', 'Priority': 'Medium'},
    {'Subject': 'Test Case 2', 'Status': 'New', 'Priority': 'High'},
    {'Subject': 'Test Case 3', 'Status': 'New', 'Priority': 'Low'}
]
result = sf.bulk_insert_records('Case', records)
print(f"Job ID: {result['job_id']}, Records Processed: {result['records_processed']}")

# Get last HTTP status code
status_code = SalesforceRESTAPI.get_last_http_status()
print(f"Last HTTP Status: {status_code}")

# Revoke authentication (clears class-level state)
sf.revoke()

Query All (pagination helper)

query_all is a convenience method that wraps the REST /queryAll endpoint and automatically pages through nextRecordsUrl to return all matching records (including archived/deleted when supported).

Usage:

# Run a SOQL using queryAll and retrieve all pages
soql = "SELECT Id, Name FROM Account WHERE CreatedDate > LAST_N_DAYS:365"
result = sf.query_all(soql)
print(f"Total records: {result['totalSize']}")
for rec in result['records'][:10]:
    print(rec.get('Id'), rec.get('Name'))

Return value:

  • A dict with keys: totalSize (int) and records (list of record dicts).
  • The method follows nextRecordsUrl until all pages are fetched.

Notes:

  • Use query_all when you expect many results or need deleted/archived records. For small queries, run_query/queryRecords is sufficient.
  • Make sure SalesforceRESTAPI.authenticate(...) is called first so class-level auth state is set.

Robot Framework Usage

You can use this library from Robot Framework by importing it as a Python library in your test suite. Below are the minimal steps to integrate:

  1. Install the package into the same Python environment used by Robot Framework:
# activate your virtualenv, then
pip install SalesforceRESTAPI
pip install robotframework
  1. Create a simple Robot Framework resource or test that imports the Python module. Example salesforce.robot:
*** Settings ***
Library    SalesforceRESTAPI

*** Variables ***
${CLIENT_ID}      your_client_id
${CLIENT_SECRET}  your_client_secret
${LOGIN_URL}      https://login.salesforce.com

*** Test Cases ***
Bulk Create Cases From List
    # Authenticate using class method (sets class-level state)
    Evaluate    SalesforceRESTAPI.authenticate('${CLIENT_ID}', '${CLIENT_SECRET}', '${LOGIN_URL}')    modules=SalesforceRESTAPI
    ${sf}=    Evaluate    SalesforceRESTAPI.SalesforceRESTAPI()    modules=SalesforceRESTAPI
    @{records}=    Create List
    ...    {'Subject': 'RF Case 1', 'Status': 'New', 'Priority': 'Medium'}
    ...    {'Subject': 'RF Case 2', 'Status': 'New', 'Priority': 'High'}
    ${result}=    Evaluate    ${sf}.bulk_insert_records('Case', ${records}, wait_for_completion=True, max_wait_seconds=60)    modules=SalesforceRESTAPI
    Log    Job ID: ${result['job_id']} | State: ${result['state']}

Notes:

  • We use Evaluate to call class methods and instance methods from Robot; alternatively you can wrap small helper keywords in a custom Robot library that calls into SalesforceRESTAPI.
  • Ensure the Robot process uses the same virtual environment where SalesforceRESTAPI is installed so dependencies like requests and python-dotenv are available.

JWT (JWT Bearer Token Flow) Authentication

Use SalesforceRESTAPI.authenticate_jwt(...) to authenticate using the JWT Bearer Token Flow (connected app / external client). This is useful when you need to impersonate a specific Salesforce user without interactive login.

Signature:

SalesforceRESTAPI.authenticate_jwt(client_id, username, private_key, login_url='https://login.salesforce.com', audience=None, private_key_is_file=True)

Parameters:

  • client_id: Connected App consumer key (the iss claim).
  • username: Salesforce username to impersonate (the sub claim).
  • private_key: Path to the PEM private key file or the PEM string itself.
  • login_url: Salesforce login URL (defaults to https://login.salesforce.com).
  • audience: Optional audience override; defaults to login_url + '/services/oauth2/token'.
  • private_key_is_file: If True and private_key is a path that exists, the file is read; otherwise private_key is used as the key material.

Return value:

  • Returns the parsed JSON auth response from Salesforce (typically contains access_token and may include instance_url). The method sets SalesforceRESTAPI.access_token and SalesforceRESTAPI.headers and will set instance_url when present in the response.

Notes and requirements:

  • Requires PyJWT and a compatible cryptography backend. Install with:
pip install PyJWT cryptography
  • If the JWT request fails, the method raises RuntimeError with the HTTP response body included to aid debugging.
  • Some orgs or endpoints may not return instance_url for JWT flows; in that case the library will only set the token and headers — set instance_url manually if required.

Example:

from SalesforceRESTAPI import SalesforceRESTAPI

# Using a private key file
auth = SalesforceRESTAPI.authenticate_jwt(
    client_id='YOUR_CONNECTED_APP_CLIENT_ID',
    username='user@example.com',
    private_key='/path/to/private_key.pem'
)

# Or using a PEM string stored in a variable
pem = open('/path/to/private_key.pem').read()
auth = SalesforceRESTAPI.authenticate_jwt(
    client_id='YOUR_CONNECTED_APP_CLIENT_ID',
    username='user@example.com',
    private_key=pem,
    private_key_is_file=False
)

# After successful auth you can construct an instance and call methods
sf = SalesforceRESTAPI()
accounts = sf.queryRecords('SELECT Id, Name FROM Account LIMIT 5')


## Requirements
- Python 3.6+
- requests
- python-dotenv (for loading .env files in tests)

## License
MIT License. See [LICENSE](LICENSE) for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

salesforcerestapi-0.2.5.tar.gz (16.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

salesforcerestapi-0.2.5-py3-none-any.whl (11.1 kB view details)

Uploaded Python 3

File details

Details for the file salesforcerestapi-0.2.5.tar.gz.

File metadata

  • Download URL: salesforcerestapi-0.2.5.tar.gz
  • Upload date:
  • Size: 16.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for salesforcerestapi-0.2.5.tar.gz
Algorithm Hash digest
SHA256 60f8ee8c911d9b63fa2e23fac51bb856cba40c8cec48b0f8cf163ec9942dc9cb
MD5 10f469683f9067646ff07e099d2723e9
BLAKE2b-256 b5a3d1ab2414fe630f3c57cfb2186012d7e1eeb387f0fbf8619970e1b7e1124e

See more details on using hashes here.

File details

Details for the file salesforcerestapi-0.2.5-py3-none-any.whl.

File metadata

File hashes

Hashes for salesforcerestapi-0.2.5-py3-none-any.whl
Algorithm Hash digest
SHA256 65d65f500075e6fb3bf3e5fe5fb22ee699385e636c3acf90892dc34698070e5c
MD5 55cdf2ca6c65cb912a8eaaa9c234179d
BLAKE2b-256 7528f88e9d868bd5a68d177dbb1f2d7fda083fd02d49b00a9e1fbf584bf1e9df

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page