Production-ready Python SDK foundation for the Procore REST API.
Project description
Procore SDK
Production-quality Python SDK and automation foundation for the Procore REST API.
The SDK handles configuration, OAuth token refresh, authenticated HTTP requests, pagination, typed response models, structured logging, and attachment downloads for companies, projects, RFIs, and submittals.
Installation
Requires Python 3.12+.
python3 -m venv .venv
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install -r requirements.txt
Configuration
Copy the example file and fill in real values:
cp .env.example .env
Required variables:
PROCORE_CLIENT_ID=your_client_id
PROCORE_CLIENT_SECRET=your_client_secret
PROCORE_REDIRECT_URI=http://localhost:8080/callback
PROCORE_LOGIN_URL=https://login.procore.com
PROCORE_API_BASE=https://api.procore.com
PROCORE_COMPANY_ID=123456
Secrets, tokens, URLs, and company IDs are never hardcoded in source.
Authentication
Exchange the first authorization code and save the token locally:
from auth.oauth import exchange_authorization_code
from auth.token_manager import TokenManager
token_response = exchange_authorization_code("authorization-code-from-procore")
TokenManager().save_oauth_response(token_response)
After that, SDK clients call:
from auth.token_manager import get_access_token
access_token = get_access_token()
Expired access tokens refresh automatically when a refresh token is available.
CLI Examples
.venv/bin/python app.py companies
.venv/bin/python app.py projects
.venv/bin/python app.py rfis --project 352338
.venv/bin/python app.py rfi --project 352338 --id 102784
.venv/bin/python app.py submittals --project 352338
.venv/bin/python app.py submittal --project 352338 --id 309641
.venv/bin/python app.py download-rfi --project 352338 --id 102784
.venv/bin/python app.py download-submittal --project 352338 --id 309641
The CLI prints nicely formatted JSON. Typed SDK models are serialized with
model_dump(mode="json").
SDK Examples
from services import (
download_rfi_attachments,
download_submittal_attachments,
get_rfi,
get_submittal,
list_companies,
list_projects,
list_rfis,
list_submittals,
)
companies = list_companies()
projects = list_projects(company_id=123456)
rfis = list_rfis(project_id=352338)
rfi = get_rfi(project_id=352338, rfi_id=102784)
first_attachment_url = rfi.questions[0].attachments[0].url
submittals = list_submittals(project_id=352338)
submittal = get_submittal(project_id=352338, submittal_id=309641)
All typed models can be serialized back to JSON:
json_payload = rfi.model_dump(mode="json")
json_string = rfi.model_dump_json()
Downloading Attachments
RFI attachments are read from:
questions[].attachments[].url
Submittal attachments are read from:
attachments[].url
Download from services:
rfi_files = download_rfi_attachments(project_id=352338, rfi_id=102784)
submittal_files = download_submittal_attachments(
project_id=352338,
submittal_id=309641,
)
The shared file service supports safe filenames, streaming writes, retries, progress logging, batch downloads, and skip-existing behavior by default.
from services.files import FileDownloadService
files = FileDownloadService().download_attachments(
attachments,
"downloads/custom",
fallback_prefix="attachment",
overwrite=False,
)
Pagination
Collection service methods use ProcoreClient.get_all(), which follows Procore
pagination headers automatically. Business logic should call the service method
or get_all() and should not manually request page 2.
Logging
The SDK writes structured logs to:
logs/sdk.log
logs/errors.log
API request logs include method, endpoint, response status, elapsed time, and retry count. Exception logs include stack traces, exception type, request URL, HTTP status, and response body when available.
The logger redacts sensitive keys such as authorization headers, access tokens, refresh tokens, and client secrets.
Architecture
auth/: OAuth exchange, token persistence, token refreshcore/: configuration, endpoint paths, HTTP client, logging, exceptionsmodels/: Pydantic response modelsservices/: company, project, RFI, submittal, and file servicesparser/: email parsing utilities for future automationtests/: mocked unit tests with no live Procore dependency
Verified Endpoint Assumptions
GET /rest/v1.0/companiesGET /rest/v1.0/companies/{company_id}/projectsGET /rest/v1.1/projects/{project_id}/rfisGET /rest/v1.1/projects/{project_id}/rfis/{rfi_id}GET /rest/v1.1/projects/{project_id}/submittalsGET /rest/v1.1/projects/{project_id}/submittals/{submittal_id}
Troubleshooting
ConfigurationError
: Check that .env exists and all required keys are present.
AuthenticationError
: Complete the first OAuth code exchange and confirm auth/token_store.json
contains a refresh token.
AuthorizationError
: Confirm the Procore user has access to the target company/project/resource.
ResourceNotFoundError
: Confirm project, RFI, or submittal IDs are correct for the configured company.
Attachment files are not downloading
: Check logs/errors.log for HTTP status and response body details. Existing
files are skipped unless overwrite=True.
Tests
Run unit tests:
.venv/bin/python -m unittest discover -s tests
Run coverage:
.venv/bin/python -m coverage run -m unittest discover -s tests
.venv/bin/python -m coverage report
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyprocore-1.0.0.tar.gz.
File metadata
- Download URL: pyprocore-1.0.0.tar.gz
- Upload date:
- Size: 30.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9d86486a5d6771a8896a42618bafeec027f1c5511b99eb3f6b9da1be197a122e
|
|
| MD5 |
dfd8ea12a7891edef12f7369beca1cfb
|
|
| BLAKE2b-256 |
c717bf976a67788cdcc232a07a9f3b37f3d93398d75f12a62d8eedd199f93c47
|
File details
Details for the file pyprocore-1.0.0-py3-none-any.whl.
File metadata
- Download URL: pyprocore-1.0.0-py3-none-any.whl
- Upload date:
- Size: 30.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
25cab3754af07cc5d9b695d170397d19fdb69d56f1a2b8b1f4cd8cd13360f559
|
|
| MD5 |
03fe6098a9db00a80e2570f736f22e4d
|
|
| BLAKE2b-256 |
384994d328aa716d599cbda242c60be48f2da50951b4f2b61c8dbc4dc097cfd9
|