Skip to content

Commit eae4b55

Browse files
committed
Add Python wrapper API for uploadBlob
1 parent d8c72f2 commit eae4b55

15 files changed

Lines changed: 1157 additions & 42 deletions

python/device/iothub_client_python/src/iothub_client_python.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,36 @@ ReceiveMessageCallback(
823823
return boost::python::extract<IOTHUBMESSAGE_DISPOSITION_RESULT>(returnObject);
824824
}
825825

826+
typedef struct
827+
{
828+
boost::python::object blobUploadCallback;
829+
boost::python::object userContext;
830+
} BlobUploadContext;
831+
832+
extern "C"
833+
void
834+
BlobUploadConfirmationCallback(
835+
IOTHUB_CLIENT_FILE_UPLOAD_RESULT result,
836+
void* userContextCallback
837+
)
838+
{
839+
BlobUploadContext *blobUploadContext = (BlobUploadContext *)userContextCallback;
840+
boost::python::object blobUploadCallback = blobUploadContext->blobUploadCallback;
841+
boost::python::object userContext = blobUploadContext->userContext;
842+
{
843+
ScopedGILAcquire acquire;
844+
try {
845+
blobUploadCallback(result, userContext);
846+
}
847+
catch (const boost::python::error_already_set)
848+
{
849+
// Catch and ignore exception that is thrown in Python callback.
850+
// There is nothing we can do about it here.
851+
PyErr_Print();
852+
}
853+
}
854+
delete blobUploadContext;
855+
}
826856

827857
class IoTHubClient
828858
{
@@ -1098,6 +1128,34 @@ class IoTHubClient
10981128
}
10991129
}
11001130

1131+
void UploadToBlobAsync(
1132+
std::string destinationFileName,
1133+
std::string source,
1134+
size_t size,
1135+
boost::python::object& iotHubClientFileUploadCallback,
1136+
boost::python::object& userContext
1137+
)
1138+
{
1139+
if (!PyCallable_Check(iotHubClientFileUploadCallback.ptr()))
1140+
{
1141+
PyErr_SetString(PyExc_TypeError, "upload_to_blob expected type callable");
1142+
boost::python::throw_error_already_set();
1143+
return;
1144+
}
1145+
BlobUploadContext *blobUploadContext = new BlobUploadContext();
1146+
blobUploadContext->blobUploadCallback = iotHubClientFileUploadCallback;
1147+
blobUploadContext->userContext = userContext;
1148+
1149+
IOTHUB_CLIENT_RESULT result;
1150+
{
1151+
ScopedGILRelease release;
1152+
result = IoTHubClient_UploadToBlobAsync(iotHubClientHandle, destinationFileName.c_str(), (const unsigned char*)source.c_str(), size, BlobUploadConfirmationCallback, blobUploadContext);
1153+
}
1154+
if (result != IOTHUB_CLIENT_OK)
1155+
{
1156+
throw IoTHubClientError(__func__, result);
1157+
}
1158+
}
11011159
#ifdef SUPPORT___STR__
11021160
std::string str() const
11031161
{
@@ -1217,6 +1275,11 @@ BOOST_PYTHON_MODULE(IMPORT_NAME)
12171275
.value("MQTT", MQTT)
12181276
;
12191277

1278+
enum_<IOTHUB_CLIENT_FILE_UPLOAD_RESULT>("IoTHubClientFileUploadResult")
1279+
.value("OK", FILE_UPLOAD_OK)
1280+
.value("ERROR", FILE_UPLOAD_ERROR)
1281+
;
1282+
12201283
// classes
12211284
class_<IoTHubMap>("IoTHubMap")
12221285
.def(init<>())
@@ -1258,6 +1321,7 @@ BOOST_PYTHON_MODULE(IMPORT_NAME)
12581321
.def("set_option", &IoTHubClient::SetOption)
12591322
.def("get_send_status", &IoTHubClient::GetSendStatus)
12601323
.def("get_last_message_receive_time", &IoTHubClient::GetLastMessageReceiveTime)
1324+
.def("upload_blob_async", &IoTHubClient::UploadToBlobAsync)
12611325
// attributes
12621326
.def_readonly("protocol", &IoTHubClient::protocol)
12631327
// Python helpers

python/device/iothub_client_python/test/iothub_client_mock.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,11 @@ IOTHUB_CLIENT_RESULT IoTHubClient_SetOption(IOTHUB_CLIENT_HANDLE iotHubClientHan
195195
return IOTHUB_CLIENT_OK;
196196
}
197197

198+
IOTHUB_CLIENT_RESULT IoTHubClient_UploadToBlobAsync(IOTHUB_CLIENT_HANDLE iotHubClientHandle, const char* destinationFileName, const unsigned char* source, size_t size, IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK iotHubClientFileUploadCallback, void* context)
199+
{
200+
return IOTHUB_CLIENT_OK;
201+
}
202+
198203
// "iothub_client_version.h"
199204

200205
const char* IoTHubClient_GetVersionString(void)

python/device/iothub_client_python/windows/client/iothub_client.vcxproj

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
<GenerateDebugInformation>true</GenerateDebugInformation>
110110
<ModuleDefinitionFile>..\$(TargetName).def</ModuleDefinitionFile>
111111
<AdditionalLibraryDirectories>$(PYTHON_PATH)\libs</AdditionalLibraryDirectories>
112+
<AdditionalDependencies>crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies>
112113
</Link>
113114
<CustomBuildStep>
114115
<Command>Copy $(TargetPath) $(TargetDir)\$(TargetName).pyd</Command>
@@ -130,6 +131,7 @@
130131
<GenerateDebugInformation>true</GenerateDebugInformation>
131132
<ModuleDefinitionFile>..\$(TargetName).def</ModuleDefinitionFile>
132133
<AdditionalLibraryDirectories>$(PYTHON_PATH)\libs</AdditionalLibraryDirectories>
134+
<AdditionalDependencies>crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies>
133135
</Link>
134136
<CustomBuildStep>
135137
<Command>Copy $(TargetPath) $(TargetDir)\$(TargetName).pyd</Command>
@@ -158,6 +160,7 @@
158160
<ModuleDefinitionFile>..\$(TargetName).def</ModuleDefinitionFile>
159161
<AdditionalLibraryDirectories>$(PYTHON_PATH)\libs</AdditionalLibraryDirectories>
160162
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
163+
<AdditionalDependencies>crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies>
161164
</Link>
162165
<CustomBuildStep>
163166
<Command>Copy $(TargetPath) $(TargetDir)\$(TargetName).pyd</Command>
@@ -186,6 +189,7 @@
186189
<ModuleDefinitionFile>..\$(TargetName).def</ModuleDefinitionFile>
187190
<AdditionalLibraryDirectories>$(PYTHON_PATH)\libs</AdditionalLibraryDirectories>
188191
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
192+
<AdditionalDependencies>crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies>
189193
</Link>
190194
<CustomBuildStep>
191195
<Command>Copy $(TargetPath) $(TargetDir)\$(TargetName).pyd</Command>
@@ -198,26 +202,26 @@
198202
<ImportGroup Label="ExtensionTargets">
199203
<Import Project="..\packages\boost.1.60.0.0\build\native\boost.targets" Condition="Exists('..\packages\boost.1.60.0.0\build\native\boost.targets')" />
200204
<Import Project="..\packages\boost_python.1.60.0.0\build\native\boost_python.targets" Condition="Exists('..\packages\boost_python.1.60.0.0\build\native\boost_python.targets')" />
201-
<Import Project="..\packages\Microsoft.Azure.C.SharedUtility.1.0.10\build\native\Microsoft.Azure.C.SharedUtility.targets" Condition="Exists('..\packages\Microsoft.Azure.C.SharedUtility.1.0.10\build\native\Microsoft.Azure.C.SharedUtility.targets')" />
202-
<Import Project="..\packages\Microsoft.Azure.IoTHub.IoTHubClient.1.0.10\build\native\Microsoft.Azure.IoTHub.IoTHubClient.targets" Condition="Exists('..\packages\Microsoft.Azure.IoTHub.IoTHubClient.1.0.10\build\native\Microsoft.Azure.IoTHub.IoTHubClient.targets')" />
203-
<Import Project="..\packages\Microsoft.Azure.IoTHub.HttpTransport.1.0.10\build\native\Microsoft.Azure.IoTHub.HttpTransport.targets" Condition="Exists('..\packages\Microsoft.Azure.IoTHub.HttpTransport.1.0.10\build\native\Microsoft.Azure.IoTHub.HttpTransport.targets')" />
204-
<Import Project="..\packages\Microsoft.Azure.uamqp.1.0.10\build\native\Microsoft.Azure.uamqp.targets" Condition="Exists('..\packages\Microsoft.Azure.uamqp.1.0.10\build\native\Microsoft.Azure.uamqp.targets')" />
205-
<Import Project="..\packages\Microsoft.Azure.IoTHub.AmqpTransport.1.0.10\build\native\Microsoft.Azure.IoTHub.AmqpTransport.targets" Condition="Exists('..\packages\Microsoft.Azure.IoTHub.AmqpTransport.1.0.10\build\native\Microsoft.Azure.IoTHub.AmqpTransport.targets')" />
206-
<Import Project="..\packages\Microsoft.Azure.umqtt.1.0.9\build\native\Microsoft.Azure.umqtt.targets" Condition="Exists('..\packages\Microsoft.Azure.umqtt.1.0.9\build\native\Microsoft.Azure.umqtt.targets')" />
207-
<Import Project="..\packages\Microsoft.Azure.IoTHub.MqttTransport.1.0.10\build\native\Microsoft.Azure.IoTHub.MqttTransport.targets" Condition="Exists('..\packages\Microsoft.Azure.IoTHub.MqttTransport.1.0.10\build\native\Microsoft.Azure.IoTHub.MqttTransport.targets')" />
205+
<Import Project="..\packages\Microsoft.Azure.C.SharedUtility.1.0.11\build\native\Microsoft.Azure.C.SharedUtility.targets" Condition="Exists('..\packages\Microsoft.Azure.C.SharedUtility.1.0.11\build\native\Microsoft.Azure.C.SharedUtility.targets')" />
206+
<Import Project="..\packages\Microsoft.Azure.IoTHub.IoTHubClient.1.0.11\build\native\Microsoft.Azure.IoTHub.IoTHubClient.targets" Condition="Exists('..\packages\Microsoft.Azure.IoTHub.IoTHubClient.1.0.11\build\native\Microsoft.Azure.IoTHub.IoTHubClient.targets')" />
207+
<Import Project="..\packages\Microsoft.Azure.IoTHub.HttpTransport.1.0.11\build\native\Microsoft.Azure.IoTHub.HttpTransport.targets" Condition="Exists('..\packages\Microsoft.Azure.IoTHub.HttpTransport.1.0.11\build\native\Microsoft.Azure.IoTHub.HttpTransport.targets')" />
208+
<Import Project="..\packages\Microsoft.Azure.uamqp.1.0.11\build\native\Microsoft.Azure.uamqp.targets" Condition="Exists('..\packages\Microsoft.Azure.uamqp.1.0.11\build\native\Microsoft.Azure.uamqp.targets')" />
209+
<Import Project="..\packages\Microsoft.Azure.IoTHub.AmqpTransport.1.0.11\build\native\Microsoft.Azure.IoTHub.AmqpTransport.targets" Condition="Exists('..\packages\Microsoft.Azure.IoTHub.AmqpTransport.1.0.11\build\native\Microsoft.Azure.IoTHub.AmqpTransport.targets')" />
210+
<Import Project="..\packages\Microsoft.Azure.umqtt.1.0.10\build\native\Microsoft.Azure.umqtt.targets" Condition="Exists('..\packages\Microsoft.Azure.umqtt.1.0.10\build\native\Microsoft.Azure.umqtt.targets')" />
211+
<Import Project="..\packages\Microsoft.Azure.IoTHub.MqttTransport.1.0.11\build\native\Microsoft.Azure.IoTHub.MqttTransport.targets" Condition="Exists('..\packages\Microsoft.Azure.IoTHub.MqttTransport.1.0.11\build\native\Microsoft.Azure.IoTHub.MqttTransport.targets')" />
208212
</ImportGroup>
209213
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
210214
<PropertyGroup>
211215
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
212216
</PropertyGroup>
213217
<Error Condition="!Exists('..\packages\boost.1.60.0.0\build\native\boost.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost.1.60.0.0\build\native\boost.targets'))" />
214218
<Error Condition="!Exists('..\packages\boost_python.1.60.0.0\build\native\boost_python.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_python.1.60.0.0\build\native\boost_python.targets'))" />
215-
<Error Condition="!Exists('..\packages\Microsoft.Azure.C.SharedUtility.1.0.10\build\native\Microsoft.Azure.C.SharedUtility.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Azure.C.SharedUtility.1.0.10\build\native\Microsoft.Azure.C.SharedUtility.targets'))" />
216-
<Error Condition="!Exists('..\packages\Microsoft.Azure.IoTHub.IoTHubClient.1.0.10\build\native\Microsoft.Azure.IoTHub.IoTHubClient.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Azure.IoTHub.IoTHubClient.1.0.10\build\native\Microsoft.Azure.IoTHub.IoTHubClient.targets'))" />
217-
<Error Condition="!Exists('..\packages\Microsoft.Azure.IoTHub.HttpTransport.1.0.10\build\native\Microsoft.Azure.IoTHub.HttpTransport.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Azure.IoTHub.HttpTransport.1.0.10\build\native\Microsoft.Azure.IoTHub.HttpTransport.targets'))" />
218-
<Error Condition="!Exists('..\packages\Microsoft.Azure.uamqp.1.0.10\build\native\Microsoft.Azure.uamqp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Azure.uamqp.1.0.10\build\native\Microsoft.Azure.uamqp.targets'))" />
219-
<Error Condition="!Exists('..\packages\Microsoft.Azure.IoTHub.AmqpTransport.1.0.10\build\native\Microsoft.Azure.IoTHub.AmqpTransport.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Azure.IoTHub.AmqpTransport.1.0.10\build\native\Microsoft.Azure.IoTHub.AmqpTransport.targets'))" />
220-
<Error Condition="!Exists('..\packages\Microsoft.Azure.umqtt.1.0.9\build\native\Microsoft.Azure.umqtt.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Azure.umqtt.1.0.9\build\native\Microsoft.Azure.umqtt.targets'))" />
221-
<Error Condition="!Exists('..\packages\Microsoft.Azure.IoTHub.MqttTransport.1.0.10\build\native\Microsoft.Azure.IoTHub.MqttTransport.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Azure.IoTHub.MqttTransport.1.0.10\build\native\Microsoft.Azure.IoTHub.MqttTransport.targets'))" />
219+
<Error Condition="!Exists('..\packages\Microsoft.Azure.C.SharedUtility.1.0.11\build\native\Microsoft.Azure.C.SharedUtility.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Azure.C.SharedUtility.1.0.11\build\native\Microsoft.Azure.C.SharedUtility.targets'))" />
220+
<Error Condition="!Exists('..\packages\Microsoft.Azure.IoTHub.IoTHubClient.1.0.11\build\native\Microsoft.Azure.IoTHub.IoTHubClient.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Azure.IoTHub.IoTHubClient.1.0.11\build\native\Microsoft.Azure.IoTHub.IoTHubClient.targets'))" />
221+
<Error Condition="!Exists('..\packages\Microsoft.Azure.IoTHub.HttpTransport.1.0.11\build\native\Microsoft.Azure.IoTHub.HttpTransport.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Azure.IoTHub.HttpTransport.1.0.11\build\native\Microsoft.Azure.IoTHub.HttpTransport.targets'))" />
222+
<Error Condition="!Exists('..\packages\Microsoft.Azure.uamqp.1.0.11\build\native\Microsoft.Azure.uamqp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Azure.uamqp.1.0.11\build\native\Microsoft.Azure.uamqp.targets'))" />
223+
<Error Condition="!Exists('..\packages\Microsoft.Azure.IoTHub.AmqpTransport.1.0.11\build\native\Microsoft.Azure.IoTHub.AmqpTransport.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Azure.IoTHub.AmqpTransport.1.0.11\build\native\Microsoft.Azure.IoTHub.AmqpTransport.targets'))" />
224+
<Error Condition="!Exists('..\packages\Microsoft.Azure.umqtt.1.0.10\build\native\Microsoft.Azure.umqtt.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Azure.umqtt.1.0.10\build\native\Microsoft.Azure.umqtt.targets'))" />
225+
<Error Condition="!Exists('..\packages\Microsoft.Azure.IoTHub.MqttTransport.1.0.11\build\native\Microsoft.Azure.IoTHub.MqttTransport.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Azure.IoTHub.MqttTransport.1.0.11\build\native\Microsoft.Azure.IoTHub.MqttTransport.targets'))" />
222226
</Target>
223227
</Project>

0 commit comments

Comments
 (0)