From 06b05ef0df7bde99246484bc07e67b83f1ecf2cd Mon Sep 17 00:00:00 2001 From: Michal Date: Wed, 14 Jul 2021 19:32:34 +0200 Subject: [PATCH 1/7] add object-detection csproj + translate most code --- .../object-detection/ObjectDetection.csproj | 14 +++++ dotnet/object-detection/Program.cs | 55 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 dotnet/object-detection/ObjectDetection.csproj create mode 100644 dotnet/object-detection/Program.cs diff --git a/dotnet/object-detection/ObjectDetection.csproj b/dotnet/object-detection/ObjectDetection.csproj new file mode 100644 index 00000000..d3f77fac --- /dev/null +++ b/dotnet/object-detection/ObjectDetection.csproj @@ -0,0 +1,14 @@ + + + + Exe + net5.0 + ObjectDetection + + + + + + + + diff --git a/dotnet/object-detection/Program.cs b/dotnet/object-detection/Program.cs new file mode 100644 index 00000000..e5bb71f3 --- /dev/null +++ b/dotnet/object-detection/Program.cs @@ -0,0 +1,55 @@ +using Appwrite; +using System; +using System.IO; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace ObjectDetection +{ + class Program + { + static async Task Main(string[] args) + { + var filename = "temp.jpg"; + + // Triggered by the storage.files.create event + var payload = json.loads(Environment.GetEnvironmentVariable["APPWRITE_FUNCTION_EVENT_DATA"]); + var fileID = payload["$id"]; + + // Setup appwrite client + var client = new Client(); + client + .SetEndPoint(Environment.GetEnvironmentVariable("APPWRITE_ENDPOINT")) + .SetProject(Environment.GetEnvironmentVariable("APPWRITE_PROJECT_ID")) + .SetKey(Environment.GetEnvironmentVariable("APPWRITE_API_KEY")) + ; + + // Get the image file + var storage = new Storage(client); + var result = storage.GetFilePreview(fileID); + + // Save the file to the container + await File.WriteAllBytesAsync(fileID, result); + + // Configure API key authorization: Apikey + var configuration = new Cloudmersive.APIClient.NETCore.ImageRecognition.Client.Configuration(); + configuration.ApiKey["Apikey"] = Environment.GetEnvironmentVariable("CLOUDMERSIVE_API_KEY"); + + // create an instance of the API class + var api_instance = new Cloudmersive.APIClient.NETCore.ImageRecognition.Api.RecognizeApi(configuration); + var image_file = filename; // file | Image file to perform the operation on. Common file formats such as PNG, JPEG are supported. + + try + { + // Detect objects including types and locations in an image + var api_response = await api_instance.RecognizeDetectObjectsAsync(File.OpenRead(fileID)); + Console.WriteLine(api_response); + } + catch (System.Exception ex) + { + Console.WriteLine($"Exception when calling RecognizeApi->recognize_detect_objects: {ex}"); + } + } + } +} \ No newline at end of file From 612a30a5fa2993876b12ce96aa10767f648036c2 Mon Sep 17 00:00:00 2001 From: Michal Date: Wed, 14 Jul 2021 19:32:47 +0200 Subject: [PATCH 2/7] add gitignore --- dotnet/object-detection/.gitignore | 40 ++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 dotnet/object-detection/.gitignore diff --git a/dotnet/object-detection/.gitignore b/dotnet/object-detection/.gitignore new file mode 100644 index 00000000..2a22c406 --- /dev/null +++ b/dotnet/object-detection/.gitignore @@ -0,0 +1,40 @@ +*.swp +*.*~ +project.lock.json +.DS_Store +*.pyc +nupkg/ + +# Visual Studio Code +.vscode + +# Rider +.idea + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +msbuild.log +msbuild.err +msbuild.wrn + +# Visual Studio 2015 +.vs/ + +# Cloud Function Archive +code.tar.gz From 0a01c869f7b99f9d4c7eee2dd67db808bff42e56 Mon Sep 17 00:00:00 2001 From: Michal Date: Wed, 21 Jul 2021 22:33:48 +0200 Subject: [PATCH 3/7] working code for code deetection --- dotnet/object-detection/Program.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/dotnet/object-detection/Program.cs b/dotnet/object-detection/Program.cs index e5bb71f3..067ae59a 100644 --- a/dotnet/object-detection/Program.cs +++ b/dotnet/object-detection/Program.cs @@ -1,6 +1,8 @@ using Appwrite; using System; +using System.Collections.Generic; using System.IO; +using System.Net; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; @@ -14,10 +16,10 @@ static async Task Main(string[] args) var filename = "temp.jpg"; // Triggered by the storage.files.create event - var payload = json.loads(Environment.GetEnvironmentVariable["APPWRITE_FUNCTION_EVENT_DATA"]); + var payload = Newtonsoft.Json.JsonConvert.DeserializeObject>(Environment.GetEnvironmentVariable("APPWRITE_FUNCTION_EVENT_DATA")); var fileID = payload["$id"]; - // Setup appwrite client + // // Setup appwrite client var client = new Client(); client .SetEndPoint(Environment.GetEnvironmentVariable("APPWRITE_ENDPOINT")) @@ -29,8 +31,12 @@ static async Task Main(string[] args) var storage = new Storage(client); var result = storage.GetFilePreview(fileID); - // Save the file to the container - await File.WriteAllBytesAsync(fileID, result); + // Read bytes from the url we received + var clientt = new System.Net.WebClient(); + clientt.Headers.Add("X-Appwrite-Project", Environment.GetEnvironmentVariable("APPWRITE_PROJECT_ID")); // needed as we only get url string without projectID + var bytes = await clientt.DownloadDataTaskAsync(new Uri(result)); + //Save the file to the container + await File.WriteAllBytesAsync(filename, bytes); // Configure API key authorization: Apikey var configuration = new Cloudmersive.APIClient.NETCore.ImageRecognition.Client.Configuration(); @@ -42,8 +48,8 @@ static async Task Main(string[] args) try { - // Detect objects including types and locations in an image - var api_response = await api_instance.RecognizeDetectObjectsAsync(File.OpenRead(fileID)); + //Detect objects including types and locations in an image + var api_response = await api_instance.RecognizeDetectObjectsAsync(File.OpenRead(image_file)); Console.WriteLine(api_response); } catch (System.Exception ex) From 356abb6b3194e08ca1990386b33521de888ff5b6 Mon Sep 17 00:00:00 2001 From: Michal Date: Wed, 21 Jul 2021 22:34:00 +0200 Subject: [PATCH 4/7] update .net appwrite package --- dotnet/object-detection/ObjectDetection.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/object-detection/ObjectDetection.csproj b/dotnet/object-detection/ObjectDetection.csproj index d3f77fac..10fee2d8 100644 --- a/dotnet/object-detection/ObjectDetection.csproj +++ b/dotnet/object-detection/ObjectDetection.csproj @@ -7,7 +7,7 @@ - + From 7f7094f92090ac59aa5dca976ec3a838f76dbd33 Mon Sep 17 00:00:00 2001 From: Michal Date: Wed, 21 Jul 2021 22:34:11 +0200 Subject: [PATCH 5/7] dummy readme --- dotnet/object-detection/README.md | 47 +++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 dotnet/object-detection/README.md diff --git a/dotnet/object-detection/README.md b/dotnet/object-detection/README.md new file mode 100644 index 00000000..de0f94bf --- /dev/null +++ b/dotnet/object-detection/README.md @@ -0,0 +1,47 @@ +# 🚮 Clean up files in your storage older than XX days +A sample .NET Cloud Function for deleting files that are older than XX days on a schedule. + +## 📝 Environment Variables +Go to Settings tab of your Cloud Function. Add the following environment variables. + +* **APPWRITE_ENDPOINT** - Your Appwrite Endpoint +* **APPWRITE_PROJECT_ID** - Your Project ID +* **APPWRITE_API_KEY** - Your Appwrite API key with `files.read` and `files.write` permissions +* **DAYS_TO_EXPIRE** - Days for files to expire + +## 🚀 Building and Packaging + +To package this example as a cloud function, follow these steps. + +```bash +$ cd demos-for-functions/dotnet/storage-cleaner + +$ dotnet publish --runtime linux-x64 --framework net5.0 --no-self-contained +``` + +* Ensure that your output looks like this +``` + StorageCleaner -> ......\demos-for-functions\dotnet\storage-cleaner\bin\Debug\net5.0\linux-x64\StorageCleaner.dll + StorageCleaner -> ......\demos-for-functions\dotnet\storage-cleaner\bin\Debug\net5.0\linux-x64\publish\ +``` + +* Create a tarfile + +```bash +$ tar -C bin/Debug/net5.0/linux-x64 -zcvf code.tar.gz publish +``` + +* Navigate to the Overview Tab of your Cloud Function > Deploy Tag +* Input the command that will run your function (in this case `dotnet StorageCleaner.dll`) as your entrypoint command +* Upload your tarfile +* Click 'Activate' + +## ⏰ Schedule + +Head over to your function in the Appwrite console and under the Settings Tab, enter a reasonable schedule time (cron syntax). + +For example: + +- `*/30 * * * *` every 30 minutes +- `0 * * * *` every hour +- `0 0 * * *` every day From dbf22c2fd7362d3d8998addbefd7b2c6545aadd7 Mon Sep 17 00:00:00 2001 From: Michal Date: Thu, 22 Jul 2021 19:37:02 +0200 Subject: [PATCH 6/7] code with all fixes --- dotnet/object-detection/Program.cs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/dotnet/object-detection/Program.cs b/dotnet/object-detection/Program.cs index 067ae59a..f99fe3f8 100644 --- a/dotnet/object-detection/Program.cs +++ b/dotnet/object-detection/Program.cs @@ -15,8 +15,15 @@ static async Task Main(string[] args) { var filename = "temp.jpg"; + // .NET parser is taking first property starting with "$" as metadata + var jsonSettings = new Newtonsoft.Json.JsonSerializerSettings() + { + MetadataPropertyHandling = Newtonsoft.Json.MetadataPropertyHandling.Ignore + }; + var json = Environment.GetEnvironmentVariable("APPWRITE_FUNCTION_EVENT_DATA"); + // Triggered by the storage.files.create event - var payload = Newtonsoft.Json.JsonConvert.DeserializeObject>(Environment.GetEnvironmentVariable("APPWRITE_FUNCTION_EVENT_DATA")); + var payload = Newtonsoft.Json.JsonConvert.DeserializeObject>(json, jsonSettings); var fileID = payload["$id"]; // // Setup appwrite client @@ -29,7 +36,7 @@ static async Task Main(string[] args) // Get the image file var storage = new Storage(client); - var result = storage.GetFilePreview(fileID); + var result = storage.GetFilePreview(fileID.ToString()); // Read bytes from the url we received var clientt = new System.Net.WebClient(); @@ -50,7 +57,17 @@ static async Task Main(string[] args) { //Detect objects including types and locations in an image var api_response = await api_instance.RecognizeDetectObjectsAsync(File.OpenRead(image_file)); - Console.WriteLine(api_response); + if (api_response.Successful == true) + { + foreach (var item in api_response.Objects) + { + Console.WriteLine(item.ObjectClassName); + } + } + else + { + Console.WriteLine("It failed"); + } } catch (System.Exception ex) { From 463ff95a4b00c2b8997afabb088eebed7cecac44 Mon Sep 17 00:00:00 2001 From: Michal Date: Thu, 22 Jul 2021 19:43:58 +0200 Subject: [PATCH 7/7] readme --- dotnet/object-detection/README.md | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/dotnet/object-detection/README.md b/dotnet/object-detection/README.md index de0f94bf..7f198399 100644 --- a/dotnet/object-detection/README.md +++ b/dotnet/object-detection/README.md @@ -1,5 +1,5 @@ -# 🚮 Clean up files in your storage older than XX days -A sample .NET Cloud Function for deleting files that are older than XX days on a schedule. +# 📷 Object Detection using Cloudmersive Vision API +A sample .Net Cloud Function for object detection on an image file uploaded by the user. ## 📝 Environment Variables Go to Settings tab of your Cloud Function. Add the following environment variables. @@ -7,14 +7,19 @@ Go to Settings tab of your Cloud Function. Add the following environment variabl * **APPWRITE_ENDPOINT** - Your Appwrite Endpoint * **APPWRITE_PROJECT_ID** - Your Project ID * **APPWRITE_API_KEY** - Your Appwrite API key with `files.read` and `files.write` permissions -* **DAYS_TO_EXPIRE** - Days for files to expire +* **CLOUDMERSIVE_API_KEY** - API key acquired from https://cloudmersive.com. There is free trie. + +## 📝 Default Environment Variables +No need to add these variables, these are supplied by Appwrite itself. + +* **APPWRITE_FUNCTION_EVENT_DATA** - Your function event payload. This value is available only when your function trigger is 'event'. This variable value contains a string in JSON format with your specific event data. ## 🚀 Building and Packaging To package this example as a cloud function, follow these steps. ```bash -$ cd demos-for-functions/dotnet/storage-cleaner +$ cd demos-for-functions/dotnet/object-detection $ dotnet publish --runtime linux-x64 --framework net5.0 --no-self-contained ``` @@ -32,16 +37,8 @@ $ tar -C bin/Debug/net5.0/linux-x64 -zcvf code.tar.gz publish ``` * Navigate to the Overview Tab of your Cloud Function > Deploy Tag -* Input the command that will run your function (in this case `dotnet StorageCleaner.dll`) as your entrypoint command +* Input the command that will run your function (in this case `dotnet ObjectDetection.dll`) as your entrypoint command * Upload your tarfile * Click 'Activate' - -## ⏰ Schedule - -Head over to your function in the Appwrite console and under the Settings Tab, enter a reasonable schedule time (cron syntax). - -For example: - -- `*/30 * * * *` every 30 minutes -- `0 * * * *` every hour -- `0 0 * * *` every day +* Navigate to the Settings Tab of your Cloud Function > Events > select storage.files.create +* (optional) set Timeout to some 30s as function may timeout before fisnishing