Skip to content

Commit

Permalink
Merge pull request #189 from YisusChrist/upload-file
Browse files Browse the repository at this point in the history
Upload file
  • Loading branch information
YisusChrist authored Jan 23, 2025
2 parents d6d14b5 + 4380cfd commit 176365e
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 2 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ This Python library is designed for testing the OData API of Creatio. It include
- [Get Data from a Collection](#get-data-from-a-collection)
- [Delete a Record from a Collection](#delete-a-record-from-a-collection)
- [Handle information from the API session](#handle-information-from-the-api-session)
- [Download a file from a Collection's attachments](#download-a-file-from-a-collections-attachments)
- [Contributors](#contributors)
- [How do I contribute to creatio-api-py?](#how-do-i-contribute-to-creatio-api-py)
- [License](#license)
Expand Down Expand Up @@ -335,6 +336,23 @@ Additionally, you can modify the object's base url if needed:
api.base_url = "https://another-environment.creatio.com"
```

## Download a file from a Collection's attachments

```python
file_id = "9dc61894-a14c-dff5-b4ff-6bca9a26018d"
api.download_file("ContactFile", file_id=file_id)
```

- Response code: `200 OK`
- Response body: The file content

Additionally, you can specify the path where the file will be saved:

```python
file_id = "9dc61894-a14c-dff5-b4ff-6bca9a26018d"
api.download_file("ContactFile", file_id=file_id, path="path/to/save/file")
```

# Contributors

<a href="https://github.com/YisusChrist/creatio-api-py/graphs/contributors"><img src="https://contrib.rocks/image?repo=YisusChrist/creatio-api-py" /></a>
Expand Down
72 changes: 71 additions & 1 deletion creatio_api_py/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ def _make_request(
self,
method: str,
endpoint: str,
headers: Optional[dict[str, str]] = None,
**kwargs: Any,
) -> requests.models.Response:
"""
Expand All @@ -180,7 +181,9 @@ def _make_request(
requests.models.Response: The response from the HTTP request.
"""
url: str = f"{self.base_url}{endpoint}"
headers: dict[str, str] = self._build_headers(endpoint, method)
if not headers:
headers = {}
headers.update(self._build_headers(endpoint, method))

try:
response: requests.Response = self.__session.request(
Expand Down Expand Up @@ -457,3 +460,70 @@ def download_file(
f.write(response.content)

return response

def upload_file(
self, collection: str, entity_id: str, file_path: str | Path
) -> requests.models.Response:
"""
Upload a file to Creatio.
Args:
collection (str): The collection to upload the file to.
entity_id (str): The ID of the entity to associate the file with.
file_path (str | Path): The path to the file to upload.
Returns:
requests.models.Response: The response from the file upload request.
"""
# Read the file data to ensure the file is valid
file_path = file_path if isinstance(file_path, Path) else Path(file_path)
with open(file_path, "rb") as f:
data: bytes = f.read()

file_length: int = len(data)
parent_collection: str = collection[: -len("File")]

# Create the file in the collection table
payload: dict[str, Any] = {
"Name": file_path.name,
f"{parent_collection}Id": entity_id,
"Size": file_length,
"TotalSize": file_length,
"TypeId": "529bc2f8-0ee0-df11-971b-001d60e938c6",
}
response: requests.Response = self.add_collection_data(collection, data=payload)
response.raise_for_status()

# Get the file ID from the response
file_id: str = response.json().get("Id")
if not file_id:
raise ValueError("Could not determine the file ID from the response")

content_type = "application/pdf"
params: dict[str, str | int] = {
"fileId": file_id,
"totalFileLength": file_length,
#"mimeType": content_type,
"fileName": file_path.name,
"columnName": "Data",
"entitySchemaName": collection,
"parentColumnName": parent_collection,
"parentColumnValue": entity_id,
}

headers: dict[str, str] = {
"Content-Type": content_type,
"Content-Disposition": f"attachment; filename={file_path.name}",
}

# TODO: Fix this call, currently returns a InvalidFileSizeException error
# Probably related to content-type header and mimeType value
response = self._make_request(
"POST",
f"0/rest/FileApiService/UploadFile",
params=params,
data=data,
)
response.raise_for_status()

return response
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "creatio-api-py"
version = "1.3.0"
version = "1.3.1"
description = "Python client for Creatio OData API"
authors = [
{ name = "Alejandro González Momblán", email = "[email protected]" },
Expand Down

0 comments on commit 176365e

Please sign in to comment.