From 27c9d074a93de7c544e6ba380fa0ca9bfc650842 Mon Sep 17 00:00:00 2001 From: c0utin Date: Sat, 28 Sep 2024 11:54:55 -0300 Subject: [PATCH] feat: http request --- .github/workflows/mops-test.yml | 22 ++++++++++ .gitignore | 2 + LICENSE | 21 ++++++++++ dfx.json | 2 +- mops.toml | 10 +++++ src/parsekoto_backend/main.mo | 73 ++++++++++++++++++++++++++++++++- src/parsekoto_backend/types.mo | 56 +++++++++++++++++++++++++ 7 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/mops-test.yml create mode 100644 LICENSE create mode 100644 mops.toml create mode 100644 src/parsekoto_backend/types.mo diff --git a/.github/workflows/mops-test.yml b/.github/workflows/mops-test.yml new file mode 100644 index 0000000..16863e0 --- /dev/null +++ b/.github/workflows/mops-test.yml @@ -0,0 +1,22 @@ +name: mops test + +on: + push: + branches: + - main + - master + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: ZenVoich/setup-mops@v1 + + - name: make sure moc is installed + run: mops toolchain bin moc || mops toolchain use moc latest + + - name: run tests + run: mops test \ No newline at end of file diff --git a/.gitignore b/.gitignore index 49c89a1..13ee63a 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ dist/ # environment variables .env + +.mops diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ac56aaf --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Rafael Coutinho + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/dfx.json b/dfx.json index cd486fb..ed00fca 100644 --- a/dfx.json +++ b/dfx.json @@ -8,7 +8,7 @@ "defaults": { "build": { "args": "", - "packtool": "" + "packtool": "mops sources" } }, "output_env_file": ".env", diff --git a/mops.toml b/mops.toml new file mode 100644 index 0000000..0d33ad7 --- /dev/null +++ b/mops.toml @@ -0,0 +1,10 @@ +[package] +name = "parsekoto" +version = "1.0.0" +description = "csv parser for motoko" +repository = "https://github.com/c0utin/parsekoto" +keywords = [ "csv", "parser", "serde", "ai", "data-science", "data" ] +license = "MIT" + +[dependencies] +base = "0.13.0" diff --git a/src/parsekoto_backend/main.mo b/src/parsekoto_backend/main.mo index 540f30b..4a42032 100644 --- a/src/parsekoto_backend/main.mo +++ b/src/parsekoto_backend/main.mo @@ -1,5 +1,74 @@ +import Debug "mo:base/Debug"; +import Blob "mo:base/Blob"; +import Cycles "mo:base/ExperimentalCycles"; +import Error "mo:base/Error"; +import Array "mo:base/Array"; +import Nat8 "mo:base/Nat8"; +import Nat64 "mo:base/Nat64"; +import Text "mo:base/Text"; + +import Types "types"; + actor { - public query func greet(name : Text) : async Text { - return "Hello, " # name # "!"; + + public query func transform(raw : Types.TransformArgs) : async Types.CanisterHttpResponsePayload { + let transformed : Types.CanisterHttpResponsePayload = { + status = raw.response.status; + body = raw.response.body; + headers = [ + { + name = "Content-Security-Policy"; + value = "default-src 'self'"; + }, + { name = "Referrer-Policy"; value = "strict-origin" }, + { name = "Permissions-Policy"; value = "geolocation=(self)" }, + { + name = "Strict-Transport-Security"; + value = "max-age=63072000"; + }, + { name = "X-Frame-Options"; value = "DENY" }, + { name = "X-Content-Type-Options"; value = "nosniff" }, + ]; + }; + transformed; }; + + public func get_icp_usd_exchange(url: Text) : async Text { + + let ic : Types.IC = actor ("aaaaa-aa"); + + + let request_headers = [ + { name = "Host"; value = "raw.githubusercontent.com" }, + { name = "User-Agent"; value = "exchange_rate_canister" }, + ]; + + + let transform_context : Types.TransformContext = { + function = transform; + context = Blob.fromArray([]); + }; + + let http_request : Types.HttpRequestArgs = { + url = url; + max_response_bytes = null; + headers = request_headers; + body = null; + method = #get; + transform = ?transform_context; + }; + + Cycles.add(230_949_972_000); + + let http_response : Types.HttpResponsePayload = await ic.http_request(http_request); + + let response_body: Blob = Blob.fromArray(http_response.body); + let decoded_text: Text = switch (Text.decodeUtf8(response_body)) { + case (null) { "No value returned" }; + case (?y) { y }; + }; + + decoded_text + }; + }; diff --git a/src/parsekoto_backend/types.mo b/src/parsekoto_backend/types.mo new file mode 100644 index 0000000..afbbdb8 --- /dev/null +++ b/src/parsekoto_backend/types.mo @@ -0,0 +1,56 @@ +module Types { + + public type Timestamp = Nat64; + + public type HttpRequestArgs = { + url : Text; + max_response_bytes : ?Nat64; + headers : [HttpHeader]; + body : ?[Nat8]; + method : HttpMethod; + transform : ?TransformRawResponseFunction; + }; + + public type HttpHeader = { + name : Text; + value : Text; + }; + + public type HttpMethod = { + #get; + #post; + #head; + }; + + public type HttpResponsePayload = { + status : Nat; + headers : [HttpHeader]; + body : [Nat8]; + }; + + public type TransformRawResponseFunction = { + function : shared query TransformArgs -> async HttpResponsePayload; + context : Blob; + }; + + public type TransformArgs = { + response : HttpResponsePayload; + context : Blob; + }; + + public type CanisterHttpResponsePayload = { + status : Nat; + headers : [HttpHeader]; + body : [Nat8]; + }; + + public type TransformContext = { + function : shared query TransformArgs -> async HttpResponsePayload; + context : Blob; + }; + + public type IC = actor { + http_request : HttpRequestArgs -> async HttpResponsePayload; + }; + +}