Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 97 additions & 41 deletions ProPyCore/access/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@

from ..exceptions import raise_exception


class Base:
"""
Base class for Procore API access
"""

def __init__(self, access_token, server_url) -> None:
"""
Initializes important API access parameters
Expand All @@ -19,12 +20,18 @@ def __init__(self, access_token, server_url) -> None:
__server_url : str
base url to send GET/POST requests
"""

self.__access_token = access_token
self.__server_url = server_url

def get_request(self, api_url, additional_headers=None, params=None):
"""
Create a HTTP Get request
def get_request(
self,
api_url,
additional_headers=None,
params=None,
return_request_obj: bool = False,
):
"""Create an HTTP GET request.

Parameters
----------
Expand All @@ -34,12 +41,18 @@ def get_request(self, api_url, additional_headers=None, params=None):
additional headers beyond Authorization
params : dict, default None
GET parameters to parse
return_request_obj : bool, default False
If True, return the underlying ``requests.Response`` object
instead of the parsed JSON / default return type.

Returns
-------
response : dict
GET response in json
dict or requests.Response
By default, the GET response in JSON (``response.json()``).
If ``return_request_obj`` is True, returns the raw
``requests.Response`` object instead.
"""

if params is None:
url = self.__server_url + api_url
else:
Expand All @@ -51,32 +64,47 @@ def get_request(self, api_url, additional_headers=None, params=None):
headers[key] = value

response = requests.get(url, headers=headers)

if response.ok:
return response.json()
return response if return_request_obj else response.json()
else:
raise_exception(response)

def post_request(self, api_url, additional_headers=None, params=None, data=None, files=None):
"""
Create a HTTP Post request

def post_request(
self,
api_url,
additional_headers=None,
params=None,
data=None,
files=None,
return_request_obj: bool = False,
):
"""Create an HTTP POST request.

Parameters
----------
api_url : str
endpoint for the specific API call
additional_headers : dict, default None
additional headers beyond Authorization
params : dict, default None
Query parameters for the POST request
data : dict, default None
POST data to send
files : list of tuple, default None
open files to send to Procore
return_request_obj : bool, default False
If True, return the underlying ``requests.Response`` object
instead of the parsed JSON / default return type.

Returns
-------
response : HTTP response object
POST response details in json
dict or requests.Response
By default, the POST response in JSON (``response.json()``).
If ``return_request_obj`` is True, returns the raw
``requests.Response`` object instead.
"""

# Get URL
if params is None:
url = self.__server_url + api_url
Expand All @@ -96,35 +124,42 @@ def post_request(self, api_url, additional_headers=None, params=None, data=None,
"POST",
url,
headers=headers,
json=data # Use json parameter instead of data to properly serialize
json=data, # Use json parameter instead of data to properly serialize
)
'''
"""
print(f"Request URL: {response.request.url}")
print(f"Request Headers: {response.request.headers}")
print(f"Request Data: {response.request.body}")
'''
"""
elif data is None:
response = requests.request(
"POST",
url,
headers=headers,
files=files # use files for multipart/form-data
files=files, # use files for multipart/form-data
)
else:
response = requests.request("POST", url, headers=headers, data=data, files=files)

if response.ok:
return response.json()
return response if return_request_obj else response.json()
else:
'''
"""
print("Response Status Code:", response.status_code)
print("Response Text:", response.text)
'''
"""
raise_exception(response)

def patch_request(self, api_url, additional_headers=None, params=None, data=None, files=False):
"""
Create a HTTP PATCH request
def patch_request(
self,
api_url,
additional_headers=None,
params=None,
data=None,
files=False,
return_request_obj: bool = False,
):
"""Create an HTTP PATCH request.

Parameters
----------
Expand All @@ -135,17 +170,23 @@ def patch_request(self, api_url, additional_headers=None, params=None, data=None
params : dict, default None
PATCH parameters to parse
data : dict, default None
POST data to send
PATCH data to send
files : dict or boolean, default False
False - updating folder so use json request
False - updating folder so use JSON request
True - updating file, but no file to include
dict - updating file with new document
return_request_obj : bool, default False
If True, return the underlying ``requests.Response`` object
instead of the parsed JSON / default return type.

Returns
-------
response : HTTP response object
PATCH response details in json
dict or requests.Response
By default, the PATCH response in JSON (``response.json()``).
If ``return_request_obj`` is True, returns the raw
``requests.Response`` object instead.
"""

# Get URL
if params is None:
url = self.__server_url + api_url
Expand All @@ -157,35 +198,41 @@ def patch_request(self, api_url, additional_headers=None, params=None, data=None
if additional_headers is not None:
for key, value in additional_headers.items():
headers[key] = value

if files is False:
response = requests.patch(
url,
headers=headers,
json=data # json for folder update
json=data, # json for folder update
)
elif files is True:
response = requests.patch(
url,
headers=headers,
data=data, # data for file update
data=data, # data for file update
)
else:
response = requests.patch(
url,
headers=headers,
data=data, # data for file update
files=files
data=data, # data for file update
files=files,
)

if response.ok:
return response.json()
return response if return_request_obj else response.json()
else:
raise_exception(response)

def delete_request(self, api_url, additional_headers=None, params=None):

def delete_request(
self,
api_url,
additional_headers=None,
params=None,
return_request_obj: bool = False,
):
"""
Execute a HTTP DELETE request
Execute an HTTP DELETE request.

Parameters
----------
Expand All @@ -195,12 +242,19 @@ def delete_request(self, api_url, additional_headers=None, params=None):
additional headers beyond Authorization
params : dict, default None
DELETE parameters to parse
return_request_obj : bool, default False
If True, return the underlying ``requests.Response`` object
instead of the default status-code dict.

Returns
-------
response : HTTP response object
DELETE response details in json
dict or requests.Response
By default, a dict containing the status code,
``{"status_code": response.status_code}``.
If ``return_request_obj`` is True, returns the raw
``requests.Response`` object instead.
"""

# Get URL
if params is None:
url = self.__server_url + api_url
Expand All @@ -220,6 +274,8 @@ def delete_request(self, api_url, additional_headers=None, params=None):
)

if response.ok:
return {"status_code":response.status_code}
if return_request_obj:
return response
return {"status_code": response.status_code}
else:
raise_exception(response)
raise_exception(response)
3 changes: 2 additions & 1 deletion ProPyCore/procore.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .exceptions import *
from .access import companies, generic_tools, projects, documents, rfis, directory, submittals, tasks, budgets, direct_costs, cost_codes, time, quality, photos, permissions, change_events, drawings
from .access import base, companies, generic_tools, projects, documents, rfis, directory, submittals, tasks, budgets, direct_costs, cost_codes, time, quality, photos, permissions, change_events, drawings
import requests

class Procore:
Expand Down Expand Up @@ -44,6 +44,7 @@ def __init__(self, client_id, client_secret, redirect_uri, base_url, oauth_url)

def _init_endpoints(self):
# General
self.base_api = base.Base(access_token=self.__access_token, server_url=self.__base_url)
self.companies = companies.Companies(access_token=self.__access_token, server_url=self.__base_url)
self.projects = projects.Projects(access_token=self.__access_token, server_url=self.__base_url)
self.permissions = permissions.Permissions(access_token=self.__access_token, server_url=self.__base_url)
Expand Down
Loading