diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..a503ddd --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,8 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/dotnet +{ + "name": "C# (.NET)", + "image": "mcr.microsoft.com/devcontainers/dotnet:1-9.0-noble", + "postAttachCommand": "cat .vscode/extensions.json | jq -r .recommendations[] | xargs -n 1 code --install-extension", + "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}" +} diff --git a/.editorconfig b/.editorconfig index 0ba6c1e..b7feeac 100644 --- a/.editorconfig +++ b/.editorconfig @@ -23,4 +23,4 @@ insert_final_newline = true dotnet_diagnostic.IDE0060.severity = none # Caused by resource with no methods and no subresources dotnet_diagnostic.IDE1006.severity = none # Some names may not match up with C# conventions -dotnet_diagnostic.IDE0290.severity = none # Don't prefer primary constructors \ No newline at end of file +dotnet_diagnostic.IDE0290.severity = none # Don't prefer primary constructors diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6c17e75..accaea7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,23 @@ jobs: - name: Run lints run: ./scripts/lint + build: + timeout-minutes: 10 + name: build + runs-on: ${{ github.repository == 'stainless-sdks/scrapegraphai-csharp' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + if: github.event_name == 'push' || github.event.pull_request.head.repo.fork + + steps: + - uses: actions/checkout@v4 + + - name: Set up .NET + uses: actions/setup-dotnet@v3 + with: + dotnet-version: '8.0.x' + + - name: Build SDK + run: ./scripts/build + test: timeout-minutes: 10 name: test diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000..3d2ac0b --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "0.1.0" +} \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 636c6f9..6804ffb 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 15 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/scrapegraphai%2Fscrapegraphai-969ebada41127057e4cda129b2e7206224743b5c7fd33aa8ae062ff71b775ac9.yml -openapi_spec_hash: 2b2c2c684e6f6885398efca5f2b1f854 -config_hash: 30d69c79e34a1ea6a0405573ce30d927 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/scrapegraphai%2Fscrapegraphai-633fdeab6abaefbe666099e8f86ce6b2acc9dacff1c33a80813bb04e8e437229.yml +openapi_spec_hash: f41ec90694ca8e7233bd20cc7ff1afbf +config_hash: 6889576ba0fdc14f2c71cea09a60a0f6 diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..921dd6d --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + "recommendations": [ + "ms-dotnettools.csharp", + "editorconfig.editorconfig", + "github.vscode-github-actions", + "ms-dotnettools.vscode-dotnet-runtime", + "ms-dotnettools.csdevkit" + ], + "unwantedRecommendations": [] +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..f07a5c5 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,46 @@ +# Changelog + +## 0.1.0 (2025-10-08) + +Full Changelog: [v0.0.1...v0.1.0](https://github.com/ScrapeGraphAI/scrapegraphai-c/compare/v0.0.1...v0.1.0) + +### Features + +* add files ([d02f336](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/d02f3362c13702753d986b0d0c35a753e3d28136)) +* **client:** add switch and match helpers for unions ([ccad199](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/ccad1993a305c58d2595477e5ecc171dd798de9d)) +* **client:** allow omitting all params object when all optional ([cf7d535](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/cf7d535c8802a1328e22dbccd58bff9186029827)) +* **client:** improve signature of `trypickx` methods ([3af2386](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/3af2386fb58dc706227669f721e42ef5f45c72f6)) +* **client:** refactor exceptions ([223ca7f](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/223ca7f992e4c17f97aa5ab7a16ec15cb1557aa9)) +* **client:** refactor unions ([67d49b4](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/67d49b454eb8aa021ccaadf2f55e82352b9e61a5)) +* **client:** shorten union variant names ([5d8fbc6](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/5d8fbc62da23aadf61ee88248acb409fec9c8bad)) +* **internal:** add dedicated build job in ci ([19debc8](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/19debc832713e17708c2524bb9a09c1b967b36e5)) +* **internal:** add dev container ([09e44c5](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/09e44c597ff8074834cc50dc8ee291ec649f22f4)) + + +### Bug Fixes + +* **client:** better type names ([198d17a](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/198d17a1e81f613235b5de7413ebe317c0965af0)) +* **client:** handle multiple auth options gracefully ([fc4a269](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/fc4a26933e1a20388a8102170fac78b3f74e2c22)) +* **docs:** re-order using statements ([1529f4f](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/1529f4fa633537e3dfcf942d3898b400b074009c)) +* **internal:** remove example csproj ([29c70b5](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/29c70b55ea868332d230cba9fa9978f46db01301)) +* **internal:** remove unused null class ([4625b19](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/4625b19d0f56f102c6e2a7cb8e953e8f83956e37)) + + +### Chores + +* configure new SDK language ([f87e130](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/f87e1302fbf8f0911a99c6ac94b704df8952798b)) +* **internal:** codegen related update ([30ebeb9](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/30ebeb9bd332cb0a60dd013238811b8b7c2e781c)) +* **internal:** remove unnecessary internal aliasing ([da2adae](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/da2adaed4478e4c9dea6629e9d5f30a1c1693267)) +* **internal:** rename parameters ([136affb](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/136affb4677cc727730d120abf6f9232eda5d9b8)) +* update SDK settings ([00653bc](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/00653bcbabf976cabc53a46e0ad4c6045f559509)) + + +### Documentation + +* **client:** add more property comments ([f427733](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/f427733d982b19d0cc1012be19978f34ae729f6f)) +* fix installation instructions ([3d59690](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/3d5969023ab80e6e87b6770f15de1c4248fe5cf1)) + + +### Refactors + +* **client:** refine enum representation ([f427733](https://github.com/ScrapeGraphAI/scrapegraphai-c/commit/f427733d982b19d0cc1012be19978f34ae729f6f)) diff --git a/README.md b/README.md index 943581f..fc86bfc 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ > > This library has not yet been exhaustively tested in production environments and may be missing some features you'd expect in a stable release. As we continue development, there may be breaking changes that require updates to your code. > -> **We'd love your feedback!** Please share any suggestions, bug reports, feature requests, or general thoughts by [filing an issue](https://www.github.com/stainless-sdks/scrapegraphai-csharp/issues/new). +> **We'd love your feedback!** Please share any suggestions, bug reports, feature requests, or general thoughts by [filing an issue](https://www.github.com/ScrapeGraphAI/scrapegraphai-c/issues/new). The Scrapegraphai C# SDK provides convenient access to the [Scrapegraphai REST API](https://scrapegraphai.com) from applications written in C#. @@ -16,7 +16,8 @@ The REST API documentation can be found on [scrapegraphai.com](https://scrapegra ## Installation ```bash -dotnet add package Scrapegraphai +git clone git@github.com:ScrapeGraphAI/scrapegraphai-c.git +dotnet add reference scrapegraphai-c/src/Scrapegraphai ``` ## Requirements @@ -31,9 +32,9 @@ This library requires .NET 8 or later. See the [`examples`](examples) directory for complete and runnable examples. ```csharp +using System; using Scrapegraphai; using Scrapegraphai.Models.Smartscraper; -using System; // Configured using the SCRAPEGRAPHAI_API_KEY and SCRAPEGRAPHAI_BASE_URL environment variables ScrapegraphaiClient client = new(); @@ -82,6 +83,33 @@ To send a request to the Scrapegraphai API, build an instance of some `Params` c For example, `client.Smartscraper.Create` should be called with an instance of `SmartscraperCreateParams`, and it will return an instance of `Task`. +## Error handling + +The SDK throws custom unchecked exception types: + +- `ScrapegraphaiApiException`: Base class for API errors. See this table for which exception subclass is thrown for each HTTP status code: + +| Status | Exception | +| ------ | -------------------------------------------- | +| 400 | `ScrapegraphaiBadRequestException` | +| 401 | `ScrapegraphaiUnauthorizedException` | +| 403 | `ScrapegraphaiForbiddenException` | +| 404 | `ScrapegraphaiNotFoundException` | +| 422 | `ScrapegraphaiUnprocessableEntityException` | +| 429 | `ScrapegraphaiRateLimitException` | +| 5xx | `Scrapegraphai5xxException` | +| others | `ScrapegraphaiUnexpectedStatusCodeException` | + +Additionally, all 4xx errors inherit from `Scrapegraphai4xxException`. + +false + +- `ScrapegraphaiIOException`: I/O networking errors. + +- `ScrapegraphaiInvalidDataException`: Failure to interpret successfully parsed data. For example, when accessing a property that's supposed to be required, but the API unexpectedly omitted it from the response. + +- `ScrapegraphaiException`: Base class for all exceptions. + ## Semantic versioning This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions: @@ -91,4 +119,4 @@ This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) con We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience. -We are keen for your feedback; please open an [issue](https://www.github.com/stainless-sdks/scrapegraphai-csharp/issues) with questions, bugs, or suggestions. +We are keen for your feedback; please open an [issue](https://www.github.com/ScrapeGraphAI/scrapegraphai-c/issues) with questions, bugs, or suggestions. diff --git a/examples/.keep b/examples/.keep new file mode 100644 index 0000000..e69de29 diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 0000000..bb36019 --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,71 @@ +{ + "packages": { + ".": {} + }, + "$schema": "https://raw.githubusercontent.com/stainless-api/release-please/main/schemas/config.json", + "include-v-in-tag": true, + "include-component-in-tag": false, + "versioning": "prerelease", + "prerelease": true, + "bump-minor-pre-major": true, + "bump-patch-for-minor-pre-major": false, + "pull-request-header": "Automated Release PR", + "pull-request-title-pattern": "release: ${version}", + "changelog-sections": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "perf", + "section": "Performance Improvements" + }, + { + "type": "revert", + "section": "Reverts" + }, + { + "type": "chore", + "section": "Chores" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "style", + "section": "Styles" + }, + { + "type": "refactor", + "section": "Refactors" + }, + { + "type": "test", + "section": "Tests", + "hidden": true + }, + { + "type": "build", + "section": "Build System" + }, + { + "type": "ci", + "section": "Continuous Integration", + "hidden": true + } + ], + "release-type": "simple", + "extra-files": [ + "README.md", + { + "type": "xml", + "path": "src/Scrapegraphai/Scrapegraphai.csproj", + "xpath": "//Project/PropertyGroup/VersionPrefix" + } + ] +} \ No newline at end of file diff --git a/src/Scrapegraphai.Tests/Scrapegraphai.Tests.csproj b/src/Scrapegraphai.Tests/Scrapegraphai.Tests.csproj index ea0fc3b..16b86ea 100644 --- a/src/Scrapegraphai.Tests/Scrapegraphai.Tests.csproj +++ b/src/Scrapegraphai.Tests/Scrapegraphai.Tests.csproj @@ -4,6 +4,8 @@ false true disable + + $(NoWarn),xUnit1004 diff --git a/src/Scrapegraphai.Tests/Services/Credits/CreditServiceTest.cs b/src/Scrapegraphai.Tests/Services/Credits/CreditServiceTest.cs index eea6fa1..98b7dfc 100644 --- a/src/Scrapegraphai.Tests/Services/Credits/CreditServiceTest.cs +++ b/src/Scrapegraphai.Tests/Services/Credits/CreditServiceTest.cs @@ -7,7 +7,7 @@ public class CreditServiceTest : TestBase [Fact(Skip = "Prism tests are disabled")] public async Task Retrieve_Works() { - var credit = await this.client.Credits.Retrieve(new()); + var credit = await this.client.Credits.Retrieve(); credit.Validate(); } } diff --git a/src/Scrapegraphai.Tests/Services/Healthz/HealthzServiceTest.cs b/src/Scrapegraphai.Tests/Services/Healthz/HealthzServiceTest.cs index ef8f743..f8750e4 100644 --- a/src/Scrapegraphai.Tests/Services/Healthz/HealthzServiceTest.cs +++ b/src/Scrapegraphai.Tests/Services/Healthz/HealthzServiceTest.cs @@ -7,7 +7,7 @@ public class HealthzServiceTest : TestBase [Fact(Skip = "Prism tests are disabled")] public async Task Check_Works() { - var response = await this.client.Healthz.Check(new()); + var response = await this.client.Healthz.Check(); response.Validate(); } } diff --git a/src/Scrapegraphai.Tests/Services/Smartscraper/SmartscraperServiceTest.cs b/src/Scrapegraphai.Tests/Services/Smartscraper/SmartscraperServiceTest.cs index 709bdae..14496ae 100644 --- a/src/Scrapegraphai.Tests/Services/Smartscraper/SmartscraperServiceTest.cs +++ b/src/Scrapegraphai.Tests/Services/Smartscraper/SmartscraperServiceTest.cs @@ -25,7 +25,7 @@ public async Task Retrieve_Works() [Fact(Skip = "Prism tests are disabled")] public async Task List_Works() { - var smartscrapers = await this.client.Smartscraper.List(new()); + var smartscrapers = await this.client.Smartscraper.List(); smartscrapers.Validate(); } } diff --git a/src/Scrapegraphai.Tests/Services/Validate/ValidateServiceTest.cs b/src/Scrapegraphai.Tests/Services/Validate/ValidateServiceTest.cs index 160441d..ac9ab72 100644 --- a/src/Scrapegraphai.Tests/Services/Validate/ValidateServiceTest.cs +++ b/src/Scrapegraphai.Tests/Services/Validate/ValidateServiceTest.cs @@ -7,7 +7,7 @@ public class ValidateServiceTest : TestBase [Fact(Skip = "Prism tests are disabled")] public async Task APIKey_Works() { - var response = await this.client.Validate.APIKey(new()); + var response = await this.client.Validate.APIKey(); response.Validate(); } } diff --git a/src/Scrapegraphai/Core/ApiEnum.cs b/src/Scrapegraphai/Core/ApiEnum.cs new file mode 100644 index 0000000..52276c7 --- /dev/null +++ b/src/Scrapegraphai/Core/ApiEnum.cs @@ -0,0 +1,59 @@ +using System; +using System.Text.Json; +using System.Text.Json.Serialization; +using Scrapegraphai.Exceptions; + +namespace Scrapegraphai.Core; + +public record struct ApiEnum(JsonElement Json) + where TEnum : struct, Enum +{ + public readonly TRaw Raw() => + JsonSerializer.Deserialize(this.Json, ModelBase.SerializerOptions) + ?? throw new ScrapegraphaiInvalidDataException( + string.Format("{0} cannot be null", nameof(this.Json)) + ); + + public readonly TEnum Value() => + JsonSerializer.Deserialize(this.Json, ModelBase.SerializerOptions); + + public readonly void Validate() + { + if (!Enum.IsDefined(Value())) + { + throw new ScrapegraphaiInvalidDataException("Invalid enum value"); + } + } + + public static implicit operator TRaw(ApiEnum value) => value.Raw(); + + public static implicit operator TEnum(ApiEnum value) => value.Value(); + + public static implicit operator ApiEnum(TRaw value) => + new(JsonSerializer.SerializeToElement(value, ModelBase.SerializerOptions)); + + public static implicit operator ApiEnum(TEnum value) => + new(JsonSerializer.SerializeToElement(value, ModelBase.SerializerOptions)); +} + +sealed class ApiEnumConverter : JsonConverter> + where TEnum : struct, Enum +{ + public override ApiEnum Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) + { + return new(JsonSerializer.Deserialize(ref reader, options)); + } + + public override void Write( + Utf8JsonWriter writer, + ApiEnum value, + JsonSerializerOptions options + ) + { + JsonSerializer.Serialize(writer, value.Json, options); + } +} diff --git a/src/Scrapegraphai/Core/HttpRequest.cs b/src/Scrapegraphai/Core/HttpRequest.cs new file mode 100644 index 0000000..4b30f85 --- /dev/null +++ b/src/Scrapegraphai/Core/HttpRequest.cs @@ -0,0 +1,11 @@ +using System.Net.Http; + +namespace Scrapegraphai.Core; + +public sealed class HttpRequest

+ where P : ParamsBase +{ + public required HttpMethod Method { get; init; } + + public required P Params { get; init; } +} diff --git a/src/Scrapegraphai/Core/HttpResponse.cs b/src/Scrapegraphai/Core/HttpResponse.cs new file mode 100644 index 0000000..1577205 --- /dev/null +++ b/src/Scrapegraphai/Core/HttpResponse.cs @@ -0,0 +1,32 @@ +using System; +using System.Net.Http; +using System.Text.Json; +using System.Threading.Tasks; +using Scrapegraphai.Exceptions; + +namespace Scrapegraphai.Core; + +public sealed class HttpResponse : IDisposable +{ + public required HttpResponseMessage Message { get; init; } + + public async Task Deserialize() + { + try + { + return JsonSerializer.Deserialize( + await Message.Content.ReadAsStreamAsync().ConfigureAwait(false), + ModelBase.SerializerOptions + ) ?? throw new ScrapegraphaiInvalidDataException("Response cannot be null"); + } + catch (HttpRequestException e) + { + throw new ScrapegraphaiIOException("I/O Exception", e); + } + } + + public void Dispose() + { + this.Message.Dispose(); + } +} diff --git a/src/Scrapegraphai/IVariant.cs b/src/Scrapegraphai/Core/IVariant.cs similarity index 81% rename from src/Scrapegraphai/IVariant.cs rename to src/Scrapegraphai/Core/IVariant.cs index 3928b0d..2517cd1 100644 --- a/src/Scrapegraphai/IVariant.cs +++ b/src/Scrapegraphai/Core/IVariant.cs @@ -1,4 +1,4 @@ -namespace Scrapegraphai; +namespace Scrapegraphai.Core; interface IVariant where TVariant : IVariant diff --git a/src/Scrapegraphai/Core/ModelBase.cs b/src/Scrapegraphai/Core/ModelBase.cs new file mode 100644 index 0000000..b562ae5 --- /dev/null +++ b/src/Scrapegraphai/Core/ModelBase.cs @@ -0,0 +1,53 @@ +using System.Collections.Generic; +using System.Text.Json; +using Scrapegraphai.Models.Smartscraper.CompletedSmartscraperProperties; +using CompletedMarkdownifyProperties = Scrapegraphai.Models.Markdownify.CompletedMarkdownifyProperties; +using CompletedSchemaGenerationResponseProperties = Scrapegraphai.Models.GenerateSchema.GenerateSchemaRetrieveResponseProperties.CompletedSchemaGenerationResponseProperties; +using CompletedSearchScraperProperties = Scrapegraphai.Models.Searchscraper.CompletedSearchScraperProperties; +using CrawlRetrieveResultsResponseProperties = Scrapegraphai.Models.Crawl.CrawlRetrieveResultsResponseProperties; +using FailedMarkdownifyResponseProperties = Scrapegraphai.Models.Markdownify.MarkdownifyRetrieveStatusResponseProperties.FailedMarkdownifyResponseProperties; +using FailedSchemaGenerationResponseProperties = Scrapegraphai.Models.GenerateSchema.GenerateSchemaRetrieveResponseProperties.FailedSchemaGenerationResponseProperties; +using FailedSearchScraperResponseProperties = Scrapegraphai.Models.Searchscraper.SearchscraperRetrieveStatusResponseProperties.FailedSearchScraperResponseProperties; +using FailedSmartscraperProperties = Scrapegraphai.Models.Smartscraper.FailedSmartscraperProperties; +using GenerateSchemaCreateResponseProperties = Scrapegraphai.Models.GenerateSchema.GenerateSchemaCreateResponseProperties; + +namespace Scrapegraphai.Core; + +public abstract record class ModelBase +{ + public Dictionary Properties { get; set; } = []; + + internal static readonly JsonSerializerOptions SerializerOptions = new() + { + Converters = + { + new ApiEnumConverter(), + new ApiEnumConverter(), + new ApiEnumConverter(), + new ApiEnumConverter(), + new ApiEnumConverter(), + new ApiEnumConverter(), + new ApiEnumConverter(), + new ApiEnumConverter(), + new ApiEnumConverter(), + new ApiEnumConverter(), + }, + }; + + static readonly JsonSerializerOptions _toStringSerializerOptions = new(SerializerOptions) + { + WriteIndented = true, + }; + + public sealed override string? ToString() + { + return JsonSerializer.Serialize(this.Properties, _toStringSerializerOptions); + } + + public abstract void Validate(); +} + +interface IFromRaw +{ + static abstract T FromRawUnchecked(Dictionary properties); +} diff --git a/src/Scrapegraphai/Core/ModelConverter.cs b/src/Scrapegraphai/Core/ModelConverter.cs new file mode 100644 index 0000000..ac5e38e --- /dev/null +++ b/src/Scrapegraphai/Core/ModelConverter.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Scrapegraphai.Core; + +sealed class ModelConverter : JsonConverter + where TModel : ModelBase, IFromRaw +{ + public override TModel? Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) + { + Dictionary? properties = JsonSerializer.Deserialize< + Dictionary + >(ref reader, options); + if (properties == null) + return null; + + return TModel.FromRawUnchecked(properties); + } + + public override void Write(Utf8JsonWriter writer, TModel value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(writer, value.Properties, options); + } +} diff --git a/src/Scrapegraphai/ParamsBase.cs b/src/Scrapegraphai/Core/ParamsBase.cs similarity index 66% rename from src/Scrapegraphai/ParamsBase.cs rename to src/Scrapegraphai/Core/ParamsBase.cs index 355eaff..a7a4d88 100644 --- a/src/Scrapegraphai/ParamsBase.cs +++ b/src/Scrapegraphai/Core/ParamsBase.cs @@ -1,45 +1,45 @@ +using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Net.Http; using System.Text; -using Json = System.Text.Json; -using System = System; +using System.Text.Json; using Web = System.Web; -namespace Scrapegraphai; +namespace Scrapegraphai.Core; public abstract record class ParamsBase { - public Dictionary QueryProperties { get; set; } = []; + public Dictionary QueryProperties { get; set; } = []; - public Dictionary HeaderProperties { get; set; } = []; + public Dictionary HeaderProperties { get; set; } = []; - public abstract System::Uri Url(IScrapegraphaiClient client); + public abstract Uri Url(IScrapegraphaiClient client); protected static void AddQueryElementToCollection( NameValueCollection collection, string key, - Json::JsonElement element + JsonElement element ) { switch (element.ValueKind) { - case Json::JsonValueKind.Undefined: - case Json::JsonValueKind.Null: + case JsonValueKind.Undefined: + case JsonValueKind.Null: collection.Add(key, ""); break; - case Json::JsonValueKind.String: - case Json::JsonValueKind.Number: + case JsonValueKind.String: + case JsonValueKind.Number: collection.Add(key, element.ToString()); break; - case Json::JsonValueKind.True: + case JsonValueKind.True: collection.Add(key, "true"); break; - case Json::JsonValueKind.False: + case JsonValueKind.False: collection.Add(key, "false"); break; - case Json::JsonValueKind.Object: + case JsonValueKind.Object: foreach (var item in element.EnumerateObject()) { AddQueryElementToCollection( @@ -49,7 +49,7 @@ protected static void AddQueryElementToCollection( ); } break; - case Json::JsonValueKind.Array: + case JsonValueKind.Array: collection.Add( key, string.Join( @@ -59,9 +59,9 @@ protected static void AddQueryElementToCollection( x => x.ValueKind switch { - Json::JsonValueKind.Null => "", - Json::JsonValueKind.True => "true", - Json::JsonValueKind.False => "false", + JsonValueKind.Null => "", + JsonValueKind.True => "true", + JsonValueKind.False => "false", _ => x.GetString(), } ) @@ -74,26 +74,26 @@ protected static void AddQueryElementToCollection( protected static void AddHeaderElementToRequest( HttpRequestMessage request, string key, - Json::JsonElement element + JsonElement element ) { switch (element.ValueKind) { - case Json::JsonValueKind.Undefined: - case Json::JsonValueKind.Null: + case JsonValueKind.Undefined: + case JsonValueKind.Null: request.Headers.Add(key, ""); break; - case Json::JsonValueKind.String: - case Json::JsonValueKind.Number: + case JsonValueKind.String: + case JsonValueKind.Number: request.Headers.Add(key, element.ToString()); break; - case Json::JsonValueKind.True: + case JsonValueKind.True: request.Headers.Add(key, "true"); break; - case Json::JsonValueKind.False: + case JsonValueKind.False: request.Headers.Add(key, "false"); break; - case Json::JsonValueKind.Object: + case JsonValueKind.Object: foreach (var item in element.EnumerateObject()) { AddHeaderElementToRequest( @@ -103,16 +103,16 @@ protected static void AddHeaderElementToRequest( ); } break; - case Json::JsonValueKind.Array: + case JsonValueKind.Array: foreach (var item in element.EnumerateArray()) { request.Headers.Add( key, item.ValueKind switch { - Json::JsonValueKind.Null => "", - Json::JsonValueKind.True => "true", - Json::JsonValueKind.False => "false", + JsonValueKind.Null => "", + JsonValueKind.True => "true", + JsonValueKind.False => "false", _ => item.GetString(), } ); @@ -147,8 +147,21 @@ protected string QueryString(IScrapegraphaiClient client) return sb.ToString(); } + internal abstract void AddHeadersToRequest( + HttpRequestMessage request, + IScrapegraphaiClient client + ); + + internal virtual StringContent? BodyContent() + { + return null; + } + protected static void AddDefaultHeaders(HttpRequestMessage request, IScrapegraphaiClient client) { - request.Headers.Add("SGAI-APIKEY", client.APIKey); + if (client.APIKey != null) + { + request.Headers.Add("SGAI-APIKEY", client.APIKey); + } } } diff --git a/src/Scrapegraphai/Exceptions/Scrapegraphai4xxException.cs b/src/Scrapegraphai/Exceptions/Scrapegraphai4xxException.cs new file mode 100644 index 0000000..2ac569e --- /dev/null +++ b/src/Scrapegraphai/Exceptions/Scrapegraphai4xxException.cs @@ -0,0 +1,9 @@ +using System.Net.Http; + +namespace Scrapegraphai.Exceptions; + +public class Scrapegraphai4xxException : ScrapegraphaiApiException +{ + public Scrapegraphai4xxException(HttpRequestException? innerException = null) + : base(innerException) { } +} diff --git a/src/Scrapegraphai/Exceptions/Scrapegraphai5xxException.cs b/src/Scrapegraphai/Exceptions/Scrapegraphai5xxException.cs new file mode 100644 index 0000000..5d89502 --- /dev/null +++ b/src/Scrapegraphai/Exceptions/Scrapegraphai5xxException.cs @@ -0,0 +1,9 @@ +using System.Net.Http; + +namespace Scrapegraphai.Exceptions; + +public class Scrapegraphai5xxException : ScrapegraphaiApiException +{ + public Scrapegraphai5xxException(HttpRequestException? innerException = null) + : base(innerException) { } +} diff --git a/src/Scrapegraphai/Exceptions/ScrapegraphaiApiException.cs b/src/Scrapegraphai/Exceptions/ScrapegraphaiApiException.cs new file mode 100644 index 0000000..6bd5fbc --- /dev/null +++ b/src/Scrapegraphai/Exceptions/ScrapegraphaiApiException.cs @@ -0,0 +1,35 @@ +using System; +using System.Net; +using System.Net.Http; + +namespace Scrapegraphai.Exceptions; + +public class ScrapegraphaiApiException : ScrapegraphaiException +{ + public new HttpRequestException InnerException + { + get + { + if (base.InnerException == null) + { + throw new ArgumentNullException(); + } + return (HttpRequestException)base.InnerException; + } + } + + public ScrapegraphaiApiException(string message, HttpRequestException? innerException = null) + : base(message, innerException) { } + + protected ScrapegraphaiApiException(HttpRequestException? innerException) + : base(innerException) { } + + public required HttpStatusCode StatusCode { get; init; } + + public required string ResponseBody { get; init; } + + public override string Message + { + get { return string.Format("Status Code: {0}\n{1}", StatusCode, ResponseBody); } + } +} diff --git a/src/Scrapegraphai/Exceptions/ScrapegraphaiBadRequestException.cs b/src/Scrapegraphai/Exceptions/ScrapegraphaiBadRequestException.cs new file mode 100644 index 0000000..6bf15c9 --- /dev/null +++ b/src/Scrapegraphai/Exceptions/ScrapegraphaiBadRequestException.cs @@ -0,0 +1,9 @@ +using System.Net.Http; + +namespace Scrapegraphai.Exceptions; + +public class ScrapegraphaiBadRequestException : Scrapegraphai4xxException +{ + public ScrapegraphaiBadRequestException(HttpRequestException? innerException = null) + : base(innerException) { } +} diff --git a/src/Scrapegraphai/Exceptions/ScrapegraphaiException.cs b/src/Scrapegraphai/Exceptions/ScrapegraphaiException.cs new file mode 100644 index 0000000..dda98e2 --- /dev/null +++ b/src/Scrapegraphai/Exceptions/ScrapegraphaiException.cs @@ -0,0 +1,13 @@ +using System; +using System.Net.Http; + +namespace Scrapegraphai.Exceptions; + +public class ScrapegraphaiException : Exception +{ + public ScrapegraphaiException(string message, Exception? innerException = null) + : base(message, innerException) { } + + protected ScrapegraphaiException(HttpRequestException? innerException) + : base(null, innerException) { } +} diff --git a/src/Scrapegraphai/Exceptions/ScrapegraphaiExceptionFactory.cs b/src/Scrapegraphai/Exceptions/ScrapegraphaiExceptionFactory.cs new file mode 100644 index 0000000..98c27db --- /dev/null +++ b/src/Scrapegraphai/Exceptions/ScrapegraphaiExceptionFactory.cs @@ -0,0 +1,61 @@ +using System.Net; + +namespace Scrapegraphai.Exceptions; + +public class ScrapegraphaiExceptionFactory +{ + public static ScrapegraphaiApiException CreateApiException( + HttpStatusCode statusCode, + string responseBody + ) + { + return (int)statusCode switch + { + 400 => new ScrapegraphaiBadRequestException() + { + StatusCode = statusCode, + ResponseBody = responseBody, + }, + 401 => new ScrapegraphaiUnauthorizedException() + { + StatusCode = statusCode, + ResponseBody = responseBody, + }, + 403 => new ScrapegraphaiForbiddenException() + { + StatusCode = statusCode, + ResponseBody = responseBody, + }, + 404 => new ScrapegraphaiNotFoundException() + { + StatusCode = statusCode, + ResponseBody = responseBody, + }, + 422 => new ScrapegraphaiUnprocessableEntityException() + { + StatusCode = statusCode, + ResponseBody = responseBody, + }, + 429 => new ScrapegraphaiRateLimitException() + { + StatusCode = statusCode, + ResponseBody = responseBody, + }, + >= 400 and <= 499 => new Scrapegraphai4xxException() + { + StatusCode = statusCode, + ResponseBody = responseBody, + }, + >= 500 and <= 599 => new Scrapegraphai5xxException() + { + StatusCode = statusCode, + ResponseBody = responseBody, + }, + _ => new ScrapegraphaiUnexpectedStatusCodeException() + { + StatusCode = statusCode, + ResponseBody = responseBody, + }, + }; + } +} diff --git a/src/Scrapegraphai/Exceptions/ScrapegraphaiForbiddenException.cs b/src/Scrapegraphai/Exceptions/ScrapegraphaiForbiddenException.cs new file mode 100644 index 0000000..04c0c88 --- /dev/null +++ b/src/Scrapegraphai/Exceptions/ScrapegraphaiForbiddenException.cs @@ -0,0 +1,9 @@ +using System.Net.Http; + +namespace Scrapegraphai.Exceptions; + +public class ScrapegraphaiForbiddenException : Scrapegraphai4xxException +{ + public ScrapegraphaiForbiddenException(HttpRequestException? innerException = null) + : base(innerException) { } +} diff --git a/src/Scrapegraphai/Exceptions/ScrapegraphaiIOException.cs b/src/Scrapegraphai/Exceptions/ScrapegraphaiIOException.cs new file mode 100644 index 0000000..9f359e5 --- /dev/null +++ b/src/Scrapegraphai/Exceptions/ScrapegraphaiIOException.cs @@ -0,0 +1,22 @@ +using System; +using System.Net.Http; + +namespace Scrapegraphai.Exceptions; + +public class ScrapegraphaiIOException : ScrapegraphaiException +{ + public new HttpRequestException InnerException + { + get + { + if (base.InnerException == null) + { + throw new ArgumentNullException(); + } + return (HttpRequestException)base.InnerException; + } + } + + public ScrapegraphaiIOException(string message, HttpRequestException? innerException = null) + : base(message, innerException) { } +} diff --git a/src/Scrapegraphai/Exceptions/ScrapegraphaiInvalidDataException.cs b/src/Scrapegraphai/Exceptions/ScrapegraphaiInvalidDataException.cs new file mode 100644 index 0000000..db28f3f --- /dev/null +++ b/src/Scrapegraphai/Exceptions/ScrapegraphaiInvalidDataException.cs @@ -0,0 +1,9 @@ +using System; + +namespace Scrapegraphai.Exceptions; + +public class ScrapegraphaiInvalidDataException : ScrapegraphaiException +{ + public ScrapegraphaiInvalidDataException(string message, Exception? innerException = null) + : base(message, innerException) { } +} diff --git a/src/Scrapegraphai/Exceptions/ScrapegraphaiNotFoundException.cs b/src/Scrapegraphai/Exceptions/ScrapegraphaiNotFoundException.cs new file mode 100644 index 0000000..6ed60bc --- /dev/null +++ b/src/Scrapegraphai/Exceptions/ScrapegraphaiNotFoundException.cs @@ -0,0 +1,9 @@ +using System.Net.Http; + +namespace Scrapegraphai.Exceptions; + +public class ScrapegraphaiNotFoundException : Scrapegraphai4xxException +{ + public ScrapegraphaiNotFoundException(HttpRequestException? innerException = null) + : base(innerException) { } +} diff --git a/src/Scrapegraphai/Exceptions/ScrapegraphaiRateLimitException.cs b/src/Scrapegraphai/Exceptions/ScrapegraphaiRateLimitException.cs new file mode 100644 index 0000000..61f2ab8 --- /dev/null +++ b/src/Scrapegraphai/Exceptions/ScrapegraphaiRateLimitException.cs @@ -0,0 +1,9 @@ +using System.Net.Http; + +namespace Scrapegraphai.Exceptions; + +public class ScrapegraphaiRateLimitException : Scrapegraphai4xxException +{ + public ScrapegraphaiRateLimitException(HttpRequestException? innerException = null) + : base(innerException) { } +} diff --git a/src/Scrapegraphai/Exceptions/ScrapegraphaiUnauthorizedException.cs b/src/Scrapegraphai/Exceptions/ScrapegraphaiUnauthorizedException.cs new file mode 100644 index 0000000..c2d2add --- /dev/null +++ b/src/Scrapegraphai/Exceptions/ScrapegraphaiUnauthorizedException.cs @@ -0,0 +1,9 @@ +using System.Net.Http; + +namespace Scrapegraphai.Exceptions; + +public class ScrapegraphaiUnauthorizedException : Scrapegraphai4xxException +{ + public ScrapegraphaiUnauthorizedException(HttpRequestException? innerException = null) + : base(innerException) { } +} diff --git a/src/Scrapegraphai/Exceptions/ScrapegraphaiUnexpectedStatusCodeException.cs b/src/Scrapegraphai/Exceptions/ScrapegraphaiUnexpectedStatusCodeException.cs new file mode 100644 index 0000000..a82b14d --- /dev/null +++ b/src/Scrapegraphai/Exceptions/ScrapegraphaiUnexpectedStatusCodeException.cs @@ -0,0 +1,9 @@ +using System.Net.Http; + +namespace Scrapegraphai.Exceptions; + +public class ScrapegraphaiUnexpectedStatusCodeException : ScrapegraphaiApiException +{ + public ScrapegraphaiUnexpectedStatusCodeException(HttpRequestException? innerException = null) + : base(innerException) { } +} diff --git a/src/Scrapegraphai/Exceptions/ScrapegraphaiUnprocessableEntityException.cs b/src/Scrapegraphai/Exceptions/ScrapegraphaiUnprocessableEntityException.cs new file mode 100644 index 0000000..48b20bd --- /dev/null +++ b/src/Scrapegraphai/Exceptions/ScrapegraphaiUnprocessableEntityException.cs @@ -0,0 +1,9 @@ +using System.Net.Http; + +namespace Scrapegraphai.Exceptions; + +public class ScrapegraphaiUnprocessableEntityException : Scrapegraphai4xxException +{ + public ScrapegraphaiUnprocessableEntityException(HttpRequestException? innerException = null) + : base(innerException) { } +} diff --git a/src/Scrapegraphai/HttpException.cs b/src/Scrapegraphai/HttpException.cs deleted file mode 100644 index 58588dc..0000000 --- a/src/Scrapegraphai/HttpException.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Net; -using System = System; - -namespace Scrapegraphai; - -public sealed class HttpException : System::Exception -{ - public required HttpStatusCode? StatusCode { get; set; } - public required string ResponseBody { get; set; } - public override string Message - { - get - { - return string.Format( - "Status Code: {0}\n{1}", - this.StatusCode?.ToString() ?? "Unknown", - this.ResponseBody - ); - } - } - - [SetsRequiredMembers] - public HttpException(HttpStatusCode? statusCode, string responseBody) - { - this.StatusCode = statusCode; - this.ResponseBody = responseBody; - } -} diff --git a/src/Scrapegraphai/IEnum.cs b/src/Scrapegraphai/IEnum.cs deleted file mode 100644 index 297e516..0000000 --- a/src/Scrapegraphai/IEnum.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Scrapegraphai; - -interface IEnum - where TEnum : IEnum -{ - static abstract TEnum FromRaw(TValue value); - TValue Raw(); -} diff --git a/src/Scrapegraphai/IScrapegraphaiClient.cs b/src/Scrapegraphai/IScrapegraphaiClient.cs index 7dde273..87d79c7 100644 --- a/src/Scrapegraphai/IScrapegraphaiClient.cs +++ b/src/Scrapegraphai/IScrapegraphaiClient.cs @@ -1,43 +1,48 @@ -using Crawl = Scrapegraphai.Services.Crawl; -using Credits = Scrapegraphai.Services.Credits; -using Feedback = Scrapegraphai.Services.Feedback; -using GenerateSchema = Scrapegraphai.Services.GenerateSchema; -using Healthz = Scrapegraphai.Services.Healthz; -using Http = System.Net.Http; -using Markdownify = Scrapegraphai.Services.Markdownify; -using Searchscraper = Scrapegraphai.Services.Searchscraper; -using Smartscraper = Scrapegraphai.Services.Smartscraper; -using System = System; -using Validate = Scrapegraphai.Services.Validate; +using System; +using System.Net.Http; +using System.Threading.Tasks; +using Scrapegraphai.Core; +using Scrapegraphai.Services.Crawl; +using Scrapegraphai.Services.Credits; +using Scrapegraphai.Services.Feedback; +using Scrapegraphai.Services.GenerateSchema; +using Scrapegraphai.Services.Healthz; +using Scrapegraphai.Services.Markdownify; +using Scrapegraphai.Services.Searchscraper; +using Scrapegraphai.Services.Smartscraper; +using Scrapegraphai.Services.Validate; namespace Scrapegraphai; public interface IScrapegraphaiClient { - Http::HttpClient HttpClient { get; init; } + HttpClient HttpClient { get; init; } - System::Uri BaseUrl { get; init; } + Uri BaseUrl { get; init; } ///

/// API key for authentication /// string APIKey { get; init; } - Smartscraper::ISmartscraperService Smartscraper { get; } + ISmartscraperService Smartscraper { get; } - Markdownify::IMarkdownifyService Markdownify { get; } + IMarkdownifyService Markdownify { get; } - Searchscraper::ISearchscraperService Searchscraper { get; } + ISearchscraperService Searchscraper { get; } - GenerateSchema::IGenerateSchemaService GenerateSchema { get; } + IGenerateSchemaService GenerateSchema { get; } - Crawl::ICrawlService Crawl { get; } + ICrawlService Crawl { get; } - Credits::ICreditService Credits { get; } + ICreditService Credits { get; } - Validate::IValidateService Validate { get; } + IValidateService Validate { get; } - Feedback::IFeedbackService Feedback { get; } + IFeedbackService Feedback { get; } - Healthz::IHealthzService Healthz { get; } + IHealthzService Healthz { get; } + + Task Execute(HttpRequest request) + where T : ParamsBase; } diff --git a/src/Scrapegraphai/JsonConverters.cs b/src/Scrapegraphai/JsonConverters.cs deleted file mode 100644 index 7c466d6..0000000 --- a/src/Scrapegraphai/JsonConverters.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text.Json.Serialization; -using Json = System.Text.Json; -using System = System; - -namespace Scrapegraphai; - -sealed class ModelConverter : JsonConverter - where TModel : ModelBase, IFromRaw -{ - public override TModel? Read( - ref Json::Utf8JsonReader reader, - System::Type _typeToConvert, - Json::JsonSerializerOptions options - ) - { - Dictionary? properties = Json::JsonSerializer.Deserialize< - Dictionary - >(ref reader, options); - if (properties == null) - return null; - - return TModel.FromRawUnchecked(properties); - } - - public override void Write( - Json::Utf8JsonWriter writer, - TModel value, - Json::JsonSerializerOptions options - ) - { - Json::JsonSerializer.Serialize(writer, value.Properties, options); - } -} - -sealed class EnumConverter : JsonConverter - where TEnum : IEnum -{ - public override TEnum Read( - ref Json::Utf8JsonReader reader, - System::Type _typeToConvert, - Json::JsonSerializerOptions options - ) - { - return TEnum.FromRaw(Json::JsonSerializer.Deserialize(ref reader, options)!); - } - - public override void Write( - Json::Utf8JsonWriter writer, - TEnum value, - Json::JsonSerializerOptions options - ) - { - Json::JsonSerializer.Serialize(writer, value.Raw(), options); - } -} - -sealed class UnionConverter : JsonConverter - where T : class -{ - readonly List _variantTypes = Enumerable.ToList( - Enumerable.Where( - Assembly.GetExecutingAssembly().GetTypes(), - type => type.BaseType == typeof(T) - ) - ); - - public override T? Read( - ref Json::Utf8JsonReader reader, - System::Type _typeToConvert, - Json::JsonSerializerOptions options - ) - { - List exceptions = []; - foreach (var variantType in _variantTypes) - { - try - { - return Json::JsonSerializer.Deserialize(ref reader, variantType, options) as T; - } - catch (Json::JsonException e) - { - exceptions.Add(e); - } - } - throw new System::AggregateException(exceptions); - } - - public override void Write( - Json::Utf8JsonWriter writer, - T value, - Json::JsonSerializerOptions options - ) - { - var variantType = - _variantTypes.Find(type => type == value.GetType()) - ?? throw new System::ArgumentOutOfRangeException(value.GetType().Name); - Json::JsonSerializer.Serialize(writer, value, variantType, options); - } -} - -sealed class VariantConverter : JsonConverter - where TVariant : IVariant -{ - public override TVariant Read( - ref Json::Utf8JsonReader reader, - System::Type _typeToConvert, - Json::JsonSerializerOptions options - ) - { - return TVariant.From(Json::JsonSerializer.Deserialize(ref reader, options)!); - } - - public override void Write( - Json::Utf8JsonWriter writer, - TVariant value, - Json::JsonSerializerOptions options - ) - { - Json::JsonSerializer.Serialize(writer, value.Value, options); - } -} diff --git a/src/Scrapegraphai/ModelBase.cs b/src/Scrapegraphai/ModelBase.cs deleted file mode 100644 index 6fc7538..0000000 --- a/src/Scrapegraphai/ModelBase.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Collections.Generic; -using Json = System.Text.Json; - -namespace Scrapegraphai; - -public abstract record class ModelBase -{ - public Dictionary Properties { get; set; } = []; - - internal static readonly Json::JsonSerializerOptions SerializerOptions = new(); - - static readonly Json::JsonSerializerOptions _toStringSerializerOptions = new(SerializerOptions) - { - WriteIndented = true, - }; - - public sealed override string? ToString() - { - return Json::JsonSerializer.Serialize(this.Properties, _toStringSerializerOptions); - } - - public abstract void Validate(); -} - -interface IFromRaw -{ - static abstract T FromRawUnchecked(Dictionary properties); -} diff --git a/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsParams.cs b/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsParams.cs index c44186a..f3a4b68 100644 --- a/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsParams.cs +++ b/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsParams.cs @@ -1,5 +1,6 @@ +using System; using System.Net.Http; -using System = System; +using Scrapegraphai.Core; namespace Scrapegraphai.Models.Crawl; @@ -10,9 +11,9 @@ public sealed record class CrawlRetrieveResultsParams : ParamsBase { public required string TaskID; - public override System::Uri Url(IScrapegraphaiClient client) + public override Uri Url(IScrapegraphaiClient client) { - return new System::UriBuilder( + return new UriBuilder( client.BaseUrl.ToString().TrimEnd('/') + string.Format("/crawl/{0}", this.TaskID) ) { @@ -20,7 +21,10 @@ public sealed record class CrawlRetrieveResultsParams : ParamsBase }.Uri; } - public void AddHeadersToRequest(HttpRequestMessage request, IScrapegraphaiClient client) + internal override void AddHeadersToRequest( + HttpRequestMessage request, + IScrapegraphaiClient client + ) { ParamsBase.AddDefaultHeaders(request, client); foreach (var item in this.HeaderProperties) diff --git a/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsResponse.cs b/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsResponse.cs index dbe2bf2..42117f7 100644 --- a/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsResponse.cs +++ b/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsResponse.cs @@ -1,8 +1,9 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Text.Json; using System.Text.Json.Serialization; -using CrawlRetrieveResultsResponseProperties = Scrapegraphai.Models.Crawl.CrawlRetrieveResultsResponseProperties; -using Json = System.Text.Json; +using Scrapegraphai.Core; +using Scrapegraphai.Models.Crawl.CrawlRetrieveResultsResponseProperties; namespace Scrapegraphai.Models.Crawl; @@ -14,46 +15,61 @@ public sealed record class CrawlRetrieveResultsResponse /// /// Successful crawl results /// - public CrawlRetrieveResultsResponseProperties::Result? Result + public Result? Result { get { - if (!this.Properties.TryGetValue("result", out Json::JsonElement element)) + if (!this.Properties.TryGetValue("result", out JsonElement element)) return null; - return Json::JsonSerializer.Deserialize( - element, + return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + } + set + { + this.Properties["result"] = JsonSerializer.SerializeToElement( + value, ModelBase.SerializerOptions ); } - set { this.Properties["result"] = Json::JsonSerializer.SerializeToElement(value); } } - public CrawlRetrieveResultsResponseProperties::Status? Status + public ApiEnum? Status { get { - if (!this.Properties.TryGetValue("status", out Json::JsonElement element)) + if (!this.Properties.TryGetValue("status", out JsonElement element)) return null; - return Json::JsonSerializer.Deserialize( + return JsonSerializer.Deserialize?>( element, ModelBase.SerializerOptions ); } - set { this.Properties["status"] = Json::JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["status"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? TaskID { get { - if (!this.Properties.TryGetValue("task_id", out Json::JsonElement element)) + if (!this.Properties.TryGetValue("task_id", out JsonElement element)) return null; - return Json::JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + } + set + { + this.Properties["task_id"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); } - set { this.Properties["task_id"] = Json::JsonSerializer.SerializeToElement(value); } } /// @@ -63,12 +79,18 @@ public string? Traceback { get { - if (!this.Properties.TryGetValue("traceback", out Json::JsonElement element)) + if (!this.Properties.TryGetValue("traceback", out JsonElement element)) return null; - return Json::JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + } + set + { + this.Properties["traceback"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); } - set { this.Properties["traceback"] = Json::JsonSerializer.SerializeToElement(value); } } public override void Validate() @@ -83,14 +105,14 @@ public CrawlRetrieveResultsResponse() { } #pragma warning disable CS8618 [SetsRequiredMembers] - CrawlRetrieveResultsResponse(Dictionary properties) + CrawlRetrieveResultsResponse(Dictionary properties) { Properties = properties; } #pragma warning restore CS8618 public static CrawlRetrieveResultsResponse FromRawUnchecked( - Dictionary properties + Dictionary properties ) { return new(properties); diff --git a/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsResponseProperties/Result.cs b/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsResponseProperties/Result.cs index 469461a..2bccf0d 100644 --- a/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsResponseProperties/Result.cs +++ b/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsResponseProperties/Result.cs @@ -1,21 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; using System.Text.Json.Serialization; -using Json = System.Text.Json; -using ResultVariants = Scrapegraphai.Models.Crawl.CrawlRetrieveResultsResponseProperties.ResultVariants; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.Crawl.CrawlRetrieveResultsResponseProperties; /// /// Successful crawl results /// -[JsonConverter(typeof(UnionConverter))] -public abstract record class Result +[JsonConverter(typeof(ResultConverter))] +public record class Result { - internal Result() { } + public object Value { get; private init; } - public static implicit operator Result(Json::JsonElement value) => - new ResultVariants::JsonElement(value); + public Result(JsonElement value) + { + Value = value; + } - public static implicit operator Result(string value) => new ResultVariants::String(value); + public Result(string value) + { + Value = value; + } - public abstract void Validate(); + Result(UnknownVariant value) + { + Value = value; + } + + public static Result CreateUnknownVariant(JsonElement value) + { + return new(new UnknownVariant(value)); + } + + public bool TryPickJsonElement([NotNullWhen(true)] out JsonElement? value) + { + value = this.Value as JsonElement?; + return value != null; + } + + public bool TryPickString([NotNullWhen(true)] out string? value) + { + value = this.Value as string; + return value != null; + } + + public void Switch(Action jsonElement, Action @string) + { + switch (this.Value) + { + case JsonElement value: + jsonElement(value); + break; + case string value: + @string(value); + break; + default: + throw new ScrapegraphaiInvalidDataException( + "Data did not match any variant of Result" + ); + } + } + + public T Match(Func jsonElement, Func @string) + { + return this.Value switch + { + JsonElement value => jsonElement(value), + string value => @string(value), + _ => throw new ScrapegraphaiInvalidDataException( + "Data did not match any variant of Result" + ), + }; + } + + public void Validate() + { + if (this.Value is not UnknownVariant) + { + throw new ScrapegraphaiInvalidDataException("Data did not match any variant of Result"); + } + } + + private record struct UnknownVariant(JsonElement value); +} + +sealed class ResultConverter : JsonConverter +{ + public override Result? Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) + { + List exceptions = []; + + try + { + var deserialized = JsonSerializer.Deserialize(ref reader, options); + if (deserialized != null) + { + return new Result(deserialized); + } + } + catch (Exception e) when (e is JsonException || e is ScrapegraphaiInvalidDataException) + { + exceptions.Add( + new ScrapegraphaiInvalidDataException( + "Data does not match union variant 'string'", + e + ) + ); + } + + try + { + return new Result(JsonSerializer.Deserialize(ref reader, options)); + } + catch (Exception e) when (e is JsonException || e is ScrapegraphaiInvalidDataException) + { + exceptions.Add( + new ScrapegraphaiInvalidDataException( + "Data does not match union variant 'JsonElement'", + e + ) + ); + } + + throw new AggregateException(exceptions); + } + + public override void Write(Utf8JsonWriter writer, Result value, JsonSerializerOptions options) + { + object variant = value.Value; + JsonSerializer.Serialize(writer, variant, options); + } } diff --git a/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsResponseProperties/ResultVariants/All.cs b/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsResponseProperties/ResultVariants/All.cs deleted file mode 100644 index 98fdae0..0000000 --- a/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsResponseProperties/ResultVariants/All.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Text.Json.Serialization; -using Json = System.Text.Json; - -namespace Scrapegraphai.Models.Crawl.CrawlRetrieveResultsResponseProperties.ResultVariants; - -/// -/// Successful crawl results -/// -[JsonConverter(typeof(VariantConverter))] -public sealed record class JsonElement(Json::JsonElement Value) - : Result, - IVariant -{ - public static JsonElement From(Json::JsonElement value) - { - return new(value); - } - - public override void Validate() { } -} - -/// -/// Error message -/// -[JsonConverter(typeof(VariantConverter))] -public sealed record class String(string Value) : Result, IVariant -{ - public static String From(string value) - { - return new(value); - } - - public override void Validate() { } -} diff --git a/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsResponseProperties/Status.cs b/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsResponseProperties/Status.cs index 5c625f6..b4da48c 100644 --- a/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsResponseProperties/Status.cs +++ b/src/Scrapegraphai/Models/Crawl/CrawlRetrieveResultsResponseProperties/Status.cs @@ -1,59 +1,58 @@ +using System; +using System.Text.Json; using System.Text.Json.Serialization; -using System = System; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.Crawl.CrawlRetrieveResultsResponseProperties; -[JsonConverter(typeof(EnumConverter))] -public sealed record class Status(string value) : IEnum +[JsonConverter(typeof(StatusConverter))] +public enum Status { - public static readonly Status Pending = new("PENDING"); - - public static readonly Status Started = new("STARTED"); - - public static readonly Status Success = new("SUCCESS"); - - public static readonly Status Failure = new("FAILURE"); - - public static readonly Status Retry = new("RETRY"); - - public static readonly Status Revoked = new("REVOKED"); - - readonly string _value = value; + Pending, + Started, + Success, + Failure, + Retry, + Revoked, +} - public enum Value +sealed class StatusConverter : JsonConverter +{ + public override Status Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) { - Pending, - Started, - Success, - Failure, - Retry, - Revoked, - } - - public Value Known() => - _value switch + return JsonSerializer.Deserialize(ref reader, options) switch { - "PENDING" => Value.Pending, - "STARTED" => Value.Started, - "SUCCESS" => Value.Success, - "FAILURE" => Value.Failure, - "RETRY" => Value.Retry, - "REVOKED" => Value.Revoked, - _ => throw new System::ArgumentOutOfRangeException(nameof(_value)), + "PENDING" => Status.Pending, + "STARTED" => Status.Started, + "SUCCESS" => Status.Success, + "FAILURE" => Status.Failure, + "RETRY" => Status.Retry, + "REVOKED" => Status.Revoked, + _ => (Status)(-1), }; - - public string Raw() - { - return _value; - } - - public void Validate() - { - Known(); } - public static Status FromRaw(string value) + public override void Write(Utf8JsonWriter writer, Status value, JsonSerializerOptions options) { - return new(value); + JsonSerializer.Serialize( + writer, + value switch + { + Status.Pending => "PENDING", + Status.Started => "STARTED", + Status.Success => "SUCCESS", + Status.Failure => "FAILURE", + Status.Retry => "RETRY", + Status.Revoked => "REVOKED", + _ => throw new ScrapegraphaiInvalidDataException( + string.Format("Invalid value '{0}' in {1}", value, nameof(value)) + ), + }, + options + ); } } diff --git a/src/Scrapegraphai/Models/Crawl/CrawlStartParams.cs b/src/Scrapegraphai/Models/Crawl/CrawlStartParams.cs index 05a5112..59bd4fc 100644 --- a/src/Scrapegraphai/Models/Crawl/CrawlStartParams.cs +++ b/src/Scrapegraphai/Models/Crawl/CrawlStartParams.cs @@ -1,9 +1,11 @@ +using System; using System.Collections.Generic; using System.Net.Http; using System.Text; -using CrawlStartParamsProperties = Scrapegraphai.Models.Crawl.CrawlStartParamsProperties; -using Json = System.Text.Json; -using System = System; +using System.Text.Json; +using Scrapegraphai.Core; +using Scrapegraphai.Exceptions; +using Scrapegraphai.Models.Crawl.CrawlStartParamsProperties; namespace Scrapegraphai.Models.Crawl; @@ -13,7 +15,7 @@ namespace Scrapegraphai.Models.Crawl; /// public sealed record class CrawlStartParams : ParamsBase { - public Dictionary BodyProperties { get; set; } = []; + public Dictionary BodyProperties { get; set; } = []; /// /// Starting URL for crawling @@ -22,13 +24,25 @@ public required string URL { get { - if (!this.BodyProperties.TryGetValue("url", out Json::JsonElement element)) - throw new System::ArgumentOutOfRangeException("url", "Missing required argument"); - - return Json::JsonSerializer.Deserialize(element, ModelBase.SerializerOptions) - ?? throw new System::ArgumentNullException("url"); + if (!this.BodyProperties.TryGetValue("url", out JsonElement element)) + throw new ScrapegraphaiInvalidDataException( + "'url' cannot be null", + new ArgumentOutOfRangeException("url", "Missing required argument") + ); + + return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions) + ?? throw new ScrapegraphaiInvalidDataException( + "'url' cannot be null", + new ArgumentNullException("url") + ); + } + set + { + this.BodyProperties["url"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); } - set { this.BodyProperties["url"] = Json::JsonSerializer.SerializeToElement(value); } } /// @@ -38,12 +52,18 @@ public long? Depth { get { - if (!this.BodyProperties.TryGetValue("depth", out Json::JsonElement element)) + if (!this.BodyProperties.TryGetValue("depth", out JsonElement element)) return null; - return Json::JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + } + set + { + this.BodyProperties["depth"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); } - set { this.BodyProperties["depth"] = Json::JsonSerializer.SerializeToElement(value); } } /// @@ -53,14 +73,17 @@ public bool? ExtractionMode { get { - if (!this.BodyProperties.TryGetValue("extraction_mode", out Json::JsonElement element)) + if (!this.BodyProperties.TryGetValue("extraction_mode", out JsonElement element)) return null; - return Json::JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } set { - this.BodyProperties["extraction_mode"] = Json::JsonSerializer.SerializeToElement(value); + this.BodyProperties["extraction_mode"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); } } @@ -71,12 +94,18 @@ public long? MaxPages { get { - if (!this.BodyProperties.TryGetValue("max_pages", out Json::JsonElement element)) + if (!this.BodyProperties.TryGetValue("max_pages", out JsonElement element)) return null; - return Json::JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + } + set + { + this.BodyProperties["max_pages"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); } - set { this.BodyProperties["max_pages"] = Json::JsonSerializer.SerializeToElement(value); } } /// @@ -86,12 +115,18 @@ public string? Prompt { get { - if (!this.BodyProperties.TryGetValue("prompt", out Json::JsonElement element)) + if (!this.BodyProperties.TryGetValue("prompt", out JsonElement element)) return null; - return Json::JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + } + set + { + this.BodyProperties["prompt"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); } - set { this.BodyProperties["prompt"] = Json::JsonSerializer.SerializeToElement(value); } } /// @@ -101,48 +136,57 @@ public bool? RenderHeavyJs { get { - if (!this.BodyProperties.TryGetValue("render_heavy_js", out Json::JsonElement element)) + if (!this.BodyProperties.TryGetValue("render_heavy_js", out JsonElement element)) return null; - return Json::JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } set { - this.BodyProperties["render_heavy_js"] = Json::JsonSerializer.SerializeToElement(value); + this.BodyProperties["render_heavy_js"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); } } - public CrawlStartParamsProperties::Rules? Rules + public Rules? Rules { get { - if (!this.BodyProperties.TryGetValue("rules", out Json::JsonElement element)) + if (!this.BodyProperties.TryGetValue("rules", out JsonElement element)) return null; - return Json::JsonSerializer.Deserialize( - element, + return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + } + set + { + this.BodyProperties["rules"] = JsonSerializer.SerializeToElement( + value, ModelBase.SerializerOptions ); } - set { this.BodyProperties["rules"] = Json::JsonSerializer.SerializeToElement(value); } } /// /// Output schema for extraction /// - public Json::JsonElement? Schema + public JsonElement? Schema { get { - if (!this.BodyProperties.TryGetValue("schema", out Json::JsonElement element)) + if (!this.BodyProperties.TryGetValue("schema", out JsonElement element)) return null; - return Json::JsonSerializer.Deserialize( - element, + return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + } + set + { + this.BodyProperties["schema"] = JsonSerializer.SerializeToElement( + value, ModelBase.SerializerOptions ); } - set { this.BodyProperties["schema"] = Json::JsonSerializer.SerializeToElement(value); } } /// @@ -152,32 +196,41 @@ public bool? Sitemap { get { - if (!this.BodyProperties.TryGetValue("sitemap", out Json::JsonElement element)) + if (!this.BodyProperties.TryGetValue("sitemap", out JsonElement element)) return null; - return Json::JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + } + set + { + this.BodyProperties["sitemap"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); } - set { this.BodyProperties["sitemap"] = Json::JsonSerializer.SerializeToElement(value); } } - public override System::Uri Url(IScrapegraphaiClient client) + public override Uri Url(IScrapegraphaiClient client) { - return new System::UriBuilder(client.BaseUrl.ToString().TrimEnd('/') + "/crawl") + return new UriBuilder(client.BaseUrl.ToString().TrimEnd('/') + "/crawl") { Query = this.QueryString(client), }.Uri; } - public StringContent BodyContent() + internal override StringContent? BodyContent() { return new( - Json::JsonSerializer.Serialize(this.BodyProperties), + JsonSerializer.Serialize(this.BodyProperties), Encoding.UTF8, "application/json" ); } - public void AddHeadersToRequest(HttpRequestMessage request, IScrapegraphaiClient client) + internal override void AddHeadersToRequest( + HttpRequestMessage request, + IScrapegraphaiClient client + ) { ParamsBase.AddDefaultHeaders(request, client); foreach (var item in this.HeaderProperties) diff --git a/src/Scrapegraphai/Models/Crawl/CrawlStartParamsProperties/Rules.cs b/src/Scrapegraphai/Models/Crawl/CrawlStartParamsProperties/Rules.cs index 05f9ead..1dc8b5f 100644 --- a/src/Scrapegraphai/Models/Crawl/CrawlStartParamsProperties/Rules.cs +++ b/src/Scrapegraphai/Models/Crawl/CrawlStartParamsProperties/Rules.cs @@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; +using Scrapegraphai.Core; namespace Scrapegraphai.Models.Crawl.CrawlStartParamsProperties; @@ -20,7 +21,13 @@ public List? Exclude return JsonSerializer.Deserialize?>(element, ModelBase.SerializerOptions); } - set { this.Properties["exclude"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["exclude"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -35,7 +42,13 @@ public bool? SameDomain return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["same_domain"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["same_domain"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override void Validate() diff --git a/src/Scrapegraphai/Models/Crawl/CrawlStartResponse.cs b/src/Scrapegraphai/Models/Crawl/CrawlStartResponse.cs index bdf8aa3..8941006 100644 --- a/src/Scrapegraphai/Models/Crawl/CrawlStartResponse.cs +++ b/src/Scrapegraphai/Models/Crawl/CrawlStartResponse.cs @@ -1,7 +1,8 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Text.Json; using System.Text.Json.Serialization; -using Json = System.Text.Json; +using Scrapegraphai.Core; namespace Scrapegraphai.Models.Crawl; @@ -15,12 +16,18 @@ public string? TaskID { get { - if (!this.Properties.TryGetValue("task_id", out Json::JsonElement element)) + if (!this.Properties.TryGetValue("task_id", out JsonElement element)) return null; - return Json::JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + } + set + { + this.Properties["task_id"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); } - set { this.Properties["task_id"] = Json::JsonSerializer.SerializeToElement(value); } } public override void Validate() @@ -32,15 +39,13 @@ public CrawlStartResponse() { } #pragma warning disable CS8618 [SetsRequiredMembers] - CrawlStartResponse(Dictionary properties) + CrawlStartResponse(Dictionary properties) { Properties = properties; } #pragma warning restore CS8618 - public static CrawlStartResponse FromRawUnchecked( - Dictionary properties - ) + public static CrawlStartResponse FromRawUnchecked(Dictionary properties) { return new(properties); } diff --git a/src/Scrapegraphai/Models/Credits/CreditRetrieveParams.cs b/src/Scrapegraphai/Models/Credits/CreditRetrieveParams.cs index 1852494..256e100 100644 --- a/src/Scrapegraphai/Models/Credits/CreditRetrieveParams.cs +++ b/src/Scrapegraphai/Models/Credits/CreditRetrieveParams.cs @@ -1,5 +1,6 @@ using System; using System.Net.Http; +using Scrapegraphai.Core; namespace Scrapegraphai.Models.Credits; @@ -16,7 +17,10 @@ public override Uri Url(IScrapegraphaiClient client) }.Uri; } - public void AddHeadersToRequest(HttpRequestMessage request, IScrapegraphaiClient client) + internal override void AddHeadersToRequest( + HttpRequestMessage request, + IScrapegraphaiClient client + ) { ParamsBase.AddDefaultHeaders(request, client); foreach (var item in this.HeaderProperties) diff --git a/src/Scrapegraphai/Models/Credits/CreditRetrieveResponse.cs b/src/Scrapegraphai/Models/Credits/CreditRetrieveResponse.cs index 79ab16d..c68c463 100644 --- a/src/Scrapegraphai/Models/Credits/CreditRetrieveResponse.cs +++ b/src/Scrapegraphai/Models/Credits/CreditRetrieveResponse.cs @@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; +using Scrapegraphai.Core; namespace Scrapegraphai.Models.Credits; @@ -20,7 +21,13 @@ public long? RemainingCredits return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["remaining_credits"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["remaining_credits"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -35,7 +42,13 @@ public long? TotalCreditsUsed return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["total_credits_used"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["total_credits_used"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override void Validate() diff --git a/src/Scrapegraphai/Models/Feedback/FeedbackSubmitParams.cs b/src/Scrapegraphai/Models/Feedback/FeedbackSubmitParams.cs index 8179ff6..ab1a7c2 100644 --- a/src/Scrapegraphai/Models/Feedback/FeedbackSubmitParams.cs +++ b/src/Scrapegraphai/Models/Feedback/FeedbackSubmitParams.cs @@ -3,6 +3,8 @@ using System.Net.Http; using System.Text; using System.Text.Json; +using Scrapegraphai.Core; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.Feedback; @@ -21,11 +23,20 @@ public required long Rating get { if (!this.BodyProperties.TryGetValue("rating", out JsonElement element)) - throw new ArgumentOutOfRangeException("rating", "Missing required argument"); + throw new ScrapegraphaiInvalidDataException( + "'rating' cannot be null", + new ArgumentOutOfRangeException("rating", "Missing required argument") + ); return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.BodyProperties["rating"] = JsonSerializer.SerializeToElement(value); } + set + { + this.BodyProperties["rating"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -36,12 +47,24 @@ public required string RequestID get { if (!this.BodyProperties.TryGetValue("request_id", out JsonElement element)) - throw new ArgumentOutOfRangeException("request_id", "Missing required argument"); + throw new ScrapegraphaiInvalidDataException( + "'request_id' cannot be null", + new ArgumentOutOfRangeException("request_id", "Missing required argument") + ); return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions) - ?? throw new ArgumentNullException("request_id"); + ?? throw new ScrapegraphaiInvalidDataException( + "'request_id' cannot be null", + new ArgumentNullException("request_id") + ); + } + set + { + this.BodyProperties["request_id"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); } - set { this.BodyProperties["request_id"] = JsonSerializer.SerializeToElement(value); } } /// @@ -56,7 +79,13 @@ public string? FeedbackText return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.BodyProperties["feedback_text"] = JsonSerializer.SerializeToElement(value); } + set + { + this.BodyProperties["feedback_text"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override Uri Url(IScrapegraphaiClient client) @@ -67,7 +96,7 @@ public override Uri Url(IScrapegraphaiClient client) }.Uri; } - public StringContent BodyContent() + internal override StringContent? BodyContent() { return new( JsonSerializer.Serialize(this.BodyProperties), @@ -76,7 +105,10 @@ public StringContent BodyContent() ); } - public void AddHeadersToRequest(HttpRequestMessage request, IScrapegraphaiClient client) + internal override void AddHeadersToRequest( + HttpRequestMessage request, + IScrapegraphaiClient client + ) { ParamsBase.AddDefaultHeaders(request, client); foreach (var item in this.HeaderProperties) diff --git a/src/Scrapegraphai/Models/Feedback/FeedbackSubmitResponse.cs b/src/Scrapegraphai/Models/Feedback/FeedbackSubmitResponse.cs index 6943d42..cc31b3e 100644 --- a/src/Scrapegraphai/Models/Feedback/FeedbackSubmitResponse.cs +++ b/src/Scrapegraphai/Models/Feedback/FeedbackSubmitResponse.cs @@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; +using Scrapegraphai.Core; namespace Scrapegraphai.Models.Feedback; @@ -18,7 +19,13 @@ public string? FeedbackID return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["feedback_id"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["feedback_id"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public DateTime? FeedbackTimestamp @@ -30,7 +37,13 @@ public DateTime? FeedbackTimestamp return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["feedback_timestamp"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["feedback_timestamp"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? Message @@ -42,7 +55,13 @@ public string? Message return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["message"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["message"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? RequestID @@ -54,7 +73,13 @@ public string? RequestID return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["request_id"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["request_id"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override void Validate() diff --git a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaCreateParams.cs b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaCreateParams.cs index caf49b9..257fecc 100644 --- a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaCreateParams.cs +++ b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaCreateParams.cs @@ -3,6 +3,8 @@ using System.Net.Http; using System.Text; using System.Text.Json; +using Scrapegraphai.Core; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.GenerateSchema; @@ -22,12 +24,24 @@ public required string UserPrompt get { if (!this.BodyProperties.TryGetValue("user_prompt", out JsonElement element)) - throw new ArgumentOutOfRangeException("user_prompt", "Missing required argument"); + throw new ScrapegraphaiInvalidDataException( + "'user_prompt' cannot be null", + new ArgumentOutOfRangeException("user_prompt", "Missing required argument") + ); return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions) - ?? throw new ArgumentNullException("user_prompt"); + ?? throw new ScrapegraphaiInvalidDataException( + "'user_prompt' cannot be null", + new ArgumentNullException("user_prompt") + ); + } + set + { + this.BodyProperties["user_prompt"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); } - set { this.BodyProperties["user_prompt"] = JsonSerializer.SerializeToElement(value); } } /// @@ -42,7 +56,13 @@ public JsonElement? ExistingSchema return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.BodyProperties["existing_schema"] = JsonSerializer.SerializeToElement(value); } + set + { + this.BodyProperties["existing_schema"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override Uri Url(IScrapegraphaiClient client) @@ -53,7 +73,7 @@ public override Uri Url(IScrapegraphaiClient client) }.Uri; } - public StringContent BodyContent() + internal override StringContent? BodyContent() { return new( JsonSerializer.Serialize(this.BodyProperties), @@ -62,7 +82,10 @@ public StringContent BodyContent() ); } - public void AddHeadersToRequest(HttpRequestMessage request, IScrapegraphaiClient client) + internal override void AddHeadersToRequest( + HttpRequestMessage request, + IScrapegraphaiClient client + ) { ParamsBase.AddDefaultHeaders(request, client); foreach (var item in this.HeaderProperties) diff --git a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaCreateResponse.cs b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaCreateResponse.cs index 29ab8a5..d8df0a1 100644 --- a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaCreateResponse.cs +++ b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaCreateResponse.cs @@ -2,7 +2,8 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; -using GenerateSchemaCreateResponseProperties = Scrapegraphai.Models.GenerateSchema.GenerateSchemaCreateResponseProperties; +using Scrapegraphai.Core; +using Scrapegraphai.Models.GenerateSchema.GenerateSchemaCreateResponseProperties; namespace Scrapegraphai.Models.GenerateSchema; @@ -20,7 +21,13 @@ public string? Error return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["error"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["error"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -35,7 +42,13 @@ public JsonElement? GeneratedSchema return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["generated_schema"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["generated_schema"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -50,7 +63,13 @@ public string? RefinedPrompt return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["refined_prompt"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["refined_prompt"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? RequestID @@ -62,22 +81,34 @@ public string? RequestID return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["request_id"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["request_id"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } - public GenerateSchemaCreateResponseProperties::Status? Status + public ApiEnum? Status { get { if (!this.Properties.TryGetValue("status", out JsonElement element)) return null; - return JsonSerializer.Deserialize( + return JsonSerializer.Deserialize?>( element, ModelBase.SerializerOptions ); } - set { this.Properties["status"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["status"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? UserPrompt @@ -89,7 +120,13 @@ public string? UserPrompt return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["user_prompt"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["user_prompt"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override void Validate() diff --git a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaCreateResponseProperties/Status.cs b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaCreateResponseProperties/Status.cs index 4eca9ee..be065bf 100644 --- a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaCreateResponseProperties/Status.cs +++ b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaCreateResponseProperties/Status.cs @@ -1,39 +1,43 @@ using System; +using System.Text.Json; using System.Text.Json.Serialization; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.GenerateSchema.GenerateSchemaCreateResponseProperties; -[JsonConverter(typeof(EnumConverter))] -public sealed record class Status(string value) : IEnum +[JsonConverter(typeof(StatusConverter))] +public enum Status { - public static readonly Status Completed = new("completed"); - - readonly string _value = value; + Completed, +} - public enum Value +sealed class StatusConverter : JsonConverter +{ + public override Status Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) { - Completed, - } - - public Value Known() => - _value switch + return JsonSerializer.Deserialize(ref reader, options) switch { - "completed" => Value.Completed, - _ => throw new ArgumentOutOfRangeException(nameof(_value)), + "completed" => Status.Completed, + _ => (Status)(-1), }; - - public string Raw() - { - return _value; - } - - public void Validate() - { - Known(); } - public static Status FromRaw(string value) + public override void Write(Utf8JsonWriter writer, Status value, JsonSerializerOptions options) { - return new(value); + JsonSerializer.Serialize( + writer, + value switch + { + Status.Completed => "completed", + _ => throw new ScrapegraphaiInvalidDataException( + string.Format("Invalid value '{0}' in {1}", value, nameof(value)) + ), + }, + options + ); } } diff --git a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveParams.cs b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveParams.cs index 177ceda..5d81aea 100644 --- a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveParams.cs +++ b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveParams.cs @@ -1,5 +1,6 @@ using System; using System.Net.Http; +using Scrapegraphai.Core; namespace Scrapegraphai.Models.GenerateSchema; @@ -21,7 +22,10 @@ public override Uri Url(IScrapegraphaiClient client) }.Uri; } - public void AddHeadersToRequest(HttpRequestMessage request, IScrapegraphaiClient client) + internal override void AddHeadersToRequest( + HttpRequestMessage request, + IScrapegraphaiClient client + ) { ParamsBase.AddDefaultHeaders(request, client); foreach (var item in this.HeaderProperties) diff --git a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponse.cs b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponse.cs index 40674c7..5c11f97 100644 --- a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponse.cs +++ b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponse.cs @@ -1,21 +1,221 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; using System.Text.Json.Serialization; -using GenerateSchemaRetrieveResponseProperties = Scrapegraphai.Models.GenerateSchema.GenerateSchemaRetrieveResponseProperties; -using GenerateSchemaRetrieveResponseVariants = Scrapegraphai.Models.GenerateSchema.GenerateSchemaRetrieveResponseVariants; +using Scrapegraphai.Exceptions; +using Scrapegraphai.Models.GenerateSchema.GenerateSchemaRetrieveResponseProperties; namespace Scrapegraphai.Models.GenerateSchema; -[JsonConverter(typeof(UnionConverter))] -public abstract record class GenerateSchemaRetrieveResponse +[JsonConverter(typeof(GenerateSchemaRetrieveResponseConverter))] +public record class GenerateSchemaRetrieveResponse { - internal GenerateSchemaRetrieveResponse() { } + public object Value { get; private init; } - public static implicit operator GenerateSchemaRetrieveResponse( - GenerateSchemaRetrieveResponseProperties::CompletedSchemaGenerationResponse value - ) => new GenerateSchemaRetrieveResponseVariants::CompletedSchemaGenerationResponse(value); + public string? Error + { + get + { + return Match( + completedSchemaGeneration: (x) => x.Error, + failedSchemaGeneration: (x) => x.Error + ); + } + } - public static implicit operator GenerateSchemaRetrieveResponse( - GenerateSchemaRetrieveResponseProperties::FailedSchemaGenerationResponse value - ) => new GenerateSchemaRetrieveResponseVariants::FailedSchemaGenerationResponse(value); + public JsonElement? GeneratedSchema + { + get + { + return Match( + completedSchemaGeneration: (x) => x.GeneratedSchema, + failedSchemaGeneration: (x) => x.GeneratedSchema + ); + } + } - public abstract void Validate(); + public string? RefinedPrompt + { + get + { + return Match( + completedSchemaGeneration: (x) => x.RefinedPrompt, + failedSchemaGeneration: (x) => x.RefinedPrompt + ); + } + } + + public string? RequestID + { + get + { + return Match( + completedSchemaGeneration: (x) => x.RequestID, + failedSchemaGeneration: (x) => x.RequestID + ); + } + } + + public string? UserPrompt + { + get + { + return Match( + completedSchemaGeneration: (x) => x.UserPrompt, + failedSchemaGeneration: (x) => x.UserPrompt + ); + } + } + + public GenerateSchemaRetrieveResponse(CompletedSchemaGenerationResponse value) + { + Value = value; + } + + public GenerateSchemaRetrieveResponse(FailedSchemaGenerationResponse value) + { + Value = value; + } + + GenerateSchemaRetrieveResponse(UnknownVariant value) + { + Value = value; + } + + public static GenerateSchemaRetrieveResponse CreateUnknownVariant(JsonElement value) + { + return new(new UnknownVariant(value)); + } + + public bool TryPickCompletedSchemaGeneration( + [NotNullWhen(true)] out CompletedSchemaGenerationResponse? value + ) + { + value = this.Value as CompletedSchemaGenerationResponse; + return value != null; + } + + public bool TryPickFailedSchemaGeneration( + [NotNullWhen(true)] out FailedSchemaGenerationResponse? value + ) + { + value = this.Value as FailedSchemaGenerationResponse; + return value != null; + } + + public void Switch( + Action completedSchemaGeneration, + Action failedSchemaGeneration + ) + { + switch (this.Value) + { + case CompletedSchemaGenerationResponse value: + completedSchemaGeneration(value); + break; + case FailedSchemaGenerationResponse value: + failedSchemaGeneration(value); + break; + default: + throw new ScrapegraphaiInvalidDataException( + "Data did not match any variant of GenerateSchemaRetrieveResponse" + ); + } + } + + public T Match( + Func completedSchemaGeneration, + Func failedSchemaGeneration + ) + { + return this.Value switch + { + CompletedSchemaGenerationResponse value => completedSchemaGeneration(value), + FailedSchemaGenerationResponse value => failedSchemaGeneration(value), + _ => throw new ScrapegraphaiInvalidDataException( + "Data did not match any variant of GenerateSchemaRetrieveResponse" + ), + }; + } + + public void Validate() + { + if (this.Value is not UnknownVariant) + { + throw new ScrapegraphaiInvalidDataException( + "Data did not match any variant of GenerateSchemaRetrieveResponse" + ); + } + } + + private record struct UnknownVariant(JsonElement value); +} + +sealed class GenerateSchemaRetrieveResponseConverter : JsonConverter +{ + public override GenerateSchemaRetrieveResponse? Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) + { + List exceptions = []; + + try + { + var deserialized = JsonSerializer.Deserialize( + ref reader, + options + ); + if (deserialized != null) + { + deserialized.Validate(); + return new GenerateSchemaRetrieveResponse(deserialized); + } + } + catch (Exception e) when (e is JsonException || e is ScrapegraphaiInvalidDataException) + { + exceptions.Add( + new ScrapegraphaiInvalidDataException( + "Data does not match union variant 'CompletedSchemaGenerationResponse'", + e + ) + ); + } + + try + { + var deserialized = JsonSerializer.Deserialize( + ref reader, + options + ); + if (deserialized != null) + { + deserialized.Validate(); + return new GenerateSchemaRetrieveResponse(deserialized); + } + } + catch (Exception e) when (e is JsonException || e is ScrapegraphaiInvalidDataException) + { + exceptions.Add( + new ScrapegraphaiInvalidDataException( + "Data does not match union variant 'FailedSchemaGenerationResponse'", + e + ) + ); + } + + throw new AggregateException(exceptions); + } + + public override void Write( + Utf8JsonWriter writer, + GenerateSchemaRetrieveResponse value, + JsonSerializerOptions options + ) + { + object variant = value.Value; + JsonSerializer.Serialize(writer, variant, options); + } } diff --git a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseProperties/CompletedSchemaGenerationResponse.cs b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseProperties/CompletedSchemaGenerationResponse.cs index 1ffd6f9..fdeab25 100644 --- a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseProperties/CompletedSchemaGenerationResponse.cs +++ b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseProperties/CompletedSchemaGenerationResponse.cs @@ -2,7 +2,8 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; -using CompletedSchemaGenerationResponseProperties = Scrapegraphai.Models.GenerateSchema.GenerateSchemaRetrieveResponseProperties.CompletedSchemaGenerationResponseProperties; +using Scrapegraphai.Core; +using Scrapegraphai.Models.GenerateSchema.GenerateSchemaRetrieveResponseProperties.CompletedSchemaGenerationResponseProperties; namespace Scrapegraphai.Models.GenerateSchema.GenerateSchemaRetrieveResponseProperties; @@ -20,7 +21,13 @@ public string? Error return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["error"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["error"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public JsonElement? GeneratedSchema @@ -32,7 +39,13 @@ public JsonElement? GeneratedSchema return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["generated_schema"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["generated_schema"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? RefinedPrompt @@ -44,7 +57,13 @@ public string? RefinedPrompt return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["refined_prompt"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["refined_prompt"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? RequestID @@ -56,22 +75,34 @@ public string? RequestID return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["request_id"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["request_id"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } - public CompletedSchemaGenerationResponseProperties::Status? Status + public ApiEnum? Status { get { if (!this.Properties.TryGetValue("status", out JsonElement element)) return null; - return JsonSerializer.Deserialize( + return JsonSerializer.Deserialize?>( element, ModelBase.SerializerOptions ); } - set { this.Properties["status"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["status"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? UserPrompt @@ -83,7 +114,13 @@ public string? UserPrompt return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["user_prompt"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["user_prompt"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override void Validate() diff --git a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseProperties/CompletedSchemaGenerationResponseProperties/Status.cs b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseProperties/CompletedSchemaGenerationResponseProperties/Status.cs index 4d483ab..22b0cc4 100644 --- a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseProperties/CompletedSchemaGenerationResponseProperties/Status.cs +++ b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseProperties/CompletedSchemaGenerationResponseProperties/Status.cs @@ -1,39 +1,43 @@ using System; +using System.Text.Json; using System.Text.Json.Serialization; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.GenerateSchema.GenerateSchemaRetrieveResponseProperties.CompletedSchemaGenerationResponseProperties; -[JsonConverter(typeof(EnumConverter))] -public sealed record class Status(string value) : IEnum +[JsonConverter(typeof(StatusConverter))] +public enum Status { - public static readonly Status Completed = new("completed"); - - readonly string _value = value; + Completed, +} - public enum Value +sealed class StatusConverter : JsonConverter +{ + public override Status Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) { - Completed, - } - - public Value Known() => - _value switch + return JsonSerializer.Deserialize(ref reader, options) switch { - "completed" => Value.Completed, - _ => throw new ArgumentOutOfRangeException(nameof(_value)), + "completed" => Status.Completed, + _ => (Status)(-1), }; - - public string Raw() - { - return _value; - } - - public void Validate() - { - Known(); } - public static Status FromRaw(string value) + public override void Write(Utf8JsonWriter writer, Status value, JsonSerializerOptions options) { - return new(value); + JsonSerializer.Serialize( + writer, + value switch + { + Status.Completed => "completed", + _ => throw new ScrapegraphaiInvalidDataException( + string.Format("Invalid value '{0}' in {1}", value, nameof(value)) + ), + }, + options + ); } } diff --git a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseProperties/FailedSchemaGenerationResponse.cs b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseProperties/FailedSchemaGenerationResponse.cs index 71a0b4b..025a8ab 100644 --- a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseProperties/FailedSchemaGenerationResponse.cs +++ b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseProperties/FailedSchemaGenerationResponse.cs @@ -2,7 +2,8 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; -using FailedSchemaGenerationResponseProperties = Scrapegraphai.Models.GenerateSchema.GenerateSchemaRetrieveResponseProperties.FailedSchemaGenerationResponseProperties; +using Scrapegraphai.Core; +using Scrapegraphai.Models.GenerateSchema.GenerateSchemaRetrieveResponseProperties.FailedSchemaGenerationResponseProperties; namespace Scrapegraphai.Models.GenerateSchema.GenerateSchemaRetrieveResponseProperties; @@ -20,7 +21,13 @@ public string? Error return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["error"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["error"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public JsonElement? GeneratedSchema @@ -32,7 +39,13 @@ public JsonElement? GeneratedSchema return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["generated_schema"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["generated_schema"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? RefinedPrompt @@ -44,7 +57,13 @@ public string? RefinedPrompt return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["refined_prompt"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["refined_prompt"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? RequestID @@ -56,22 +75,34 @@ public string? RequestID return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["request_id"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["request_id"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } - public FailedSchemaGenerationResponseProperties::Status? Status + public ApiEnum? Status { get { if (!this.Properties.TryGetValue("status", out JsonElement element)) return null; - return JsonSerializer.Deserialize( + return JsonSerializer.Deserialize?>( element, ModelBase.SerializerOptions ); } - set { this.Properties["status"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["status"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? UserPrompt @@ -83,7 +114,13 @@ public string? UserPrompt return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["user_prompt"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["user_prompt"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override void Validate() diff --git a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseProperties/FailedSchemaGenerationResponseProperties/Status.cs b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseProperties/FailedSchemaGenerationResponseProperties/Status.cs index a48da7f..f2442c5 100644 --- a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseProperties/FailedSchemaGenerationResponseProperties/Status.cs +++ b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseProperties/FailedSchemaGenerationResponseProperties/Status.cs @@ -1,39 +1,43 @@ using System; +using System.Text.Json; using System.Text.Json.Serialization; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.GenerateSchema.GenerateSchemaRetrieveResponseProperties.FailedSchemaGenerationResponseProperties; -[JsonConverter(typeof(EnumConverter))] -public sealed record class Status(string value) : IEnum +[JsonConverter(typeof(StatusConverter))] +public enum Status { - public static readonly Status Failed = new("failed"); - - readonly string _value = value; + Failed, +} - public enum Value +sealed class StatusConverter : JsonConverter +{ + public override Status Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) { - Failed, - } - - public Value Known() => - _value switch + return JsonSerializer.Deserialize(ref reader, options) switch { - "failed" => Value.Failed, - _ => throw new ArgumentOutOfRangeException(nameof(_value)), + "failed" => Status.Failed, + _ => (Status)(-1), }; - - public string Raw() - { - return _value; - } - - public void Validate() - { - Known(); } - public static Status FromRaw(string value) + public override void Write(Utf8JsonWriter writer, Status value, JsonSerializerOptions options) { - return new(value); + JsonSerializer.Serialize( + writer, + value switch + { + Status.Failed => "failed", + _ => throw new ScrapegraphaiInvalidDataException( + string.Format("Invalid value '{0}' in {1}", value, nameof(value)) + ), + }, + options + ); } } diff --git a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseVariants/All.cs b/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseVariants/All.cs deleted file mode 100644 index 34ed2bc..0000000 --- a/src/Scrapegraphai/Models/GenerateSchema/GenerateSchemaRetrieveResponseVariants/All.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System.Text.Json.Serialization; -using GenerateSchemaRetrieveResponseProperties = Scrapegraphai.Models.GenerateSchema.GenerateSchemaRetrieveResponseProperties; - -namespace Scrapegraphai.Models.GenerateSchema.GenerateSchemaRetrieveResponseVariants; - -[JsonConverter( - typeof(VariantConverter< - CompletedSchemaGenerationResponse, - GenerateSchemaRetrieveResponseProperties::CompletedSchemaGenerationResponse - >) -)] -public sealed record class CompletedSchemaGenerationResponse( - GenerateSchemaRetrieveResponseProperties::CompletedSchemaGenerationResponse Value -) - : GenerateSchemaRetrieveResponse, - IVariant< - CompletedSchemaGenerationResponse, - GenerateSchemaRetrieveResponseProperties::CompletedSchemaGenerationResponse - > -{ - public static CompletedSchemaGenerationResponse From( - GenerateSchemaRetrieveResponseProperties::CompletedSchemaGenerationResponse value - ) - { - return new(value); - } - - public override void Validate() - { - this.Value.Validate(); - } -} - -[JsonConverter( - typeof(VariantConverter< - FailedSchemaGenerationResponse, - GenerateSchemaRetrieveResponseProperties::FailedSchemaGenerationResponse - >) -)] -public sealed record class FailedSchemaGenerationResponse( - GenerateSchemaRetrieveResponseProperties::FailedSchemaGenerationResponse Value -) - : GenerateSchemaRetrieveResponse, - IVariant< - FailedSchemaGenerationResponse, - GenerateSchemaRetrieveResponseProperties::FailedSchemaGenerationResponse - > -{ - public static FailedSchemaGenerationResponse From( - GenerateSchemaRetrieveResponseProperties::FailedSchemaGenerationResponse value - ) - { - return new(value); - } - - public override void Validate() - { - this.Value.Validate(); - } -} diff --git a/src/Scrapegraphai/Models/Healthz/HealthzCheckParams.cs b/src/Scrapegraphai/Models/Healthz/HealthzCheckParams.cs index 380c72f..6f53ad8 100644 --- a/src/Scrapegraphai/Models/Healthz/HealthzCheckParams.cs +++ b/src/Scrapegraphai/Models/Healthz/HealthzCheckParams.cs @@ -1,5 +1,6 @@ using System; using System.Net.Http; +using Scrapegraphai.Core; namespace Scrapegraphai.Models.Healthz; @@ -16,7 +17,10 @@ public override Uri Url(IScrapegraphaiClient client) }.Uri; } - public void AddHeadersToRequest(HttpRequestMessage request, IScrapegraphaiClient client) + internal override void AddHeadersToRequest( + HttpRequestMessage request, + IScrapegraphaiClient client + ) { ParamsBase.AddDefaultHeaders(request, client); foreach (var item in this.HeaderProperties) diff --git a/src/Scrapegraphai/Models/Healthz/HealthzCheckResponse.cs b/src/Scrapegraphai/Models/Healthz/HealthzCheckResponse.cs index c0add17..b923c3a 100644 --- a/src/Scrapegraphai/Models/Healthz/HealthzCheckResponse.cs +++ b/src/Scrapegraphai/Models/Healthz/HealthzCheckResponse.cs @@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; +using Scrapegraphai.Core; namespace Scrapegraphai.Models.Healthz; @@ -20,7 +21,13 @@ public Dictionary? Services ModelBase.SerializerOptions ); } - set { this.Properties["services"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["services"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? Status @@ -32,7 +39,13 @@ public string? Status return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["status"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["status"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override void Validate() diff --git a/src/Scrapegraphai/Models/Markdownify/CompletedMarkdownify.cs b/src/Scrapegraphai/Models/Markdownify/CompletedMarkdownify.cs index 57e9bb3..2bb137d 100644 --- a/src/Scrapegraphai/Models/Markdownify/CompletedMarkdownify.cs +++ b/src/Scrapegraphai/Models/Markdownify/CompletedMarkdownify.cs @@ -2,7 +2,8 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; -using CompletedMarkdownifyProperties = Scrapegraphai.Models.Markdownify.CompletedMarkdownifyProperties; +using Scrapegraphai.Core; +using Scrapegraphai.Models.Markdownify.CompletedMarkdownifyProperties; namespace Scrapegraphai.Models.Markdownify; @@ -18,7 +19,13 @@ public string? Error return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["error"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["error"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? RequestID @@ -30,7 +37,13 @@ public string? RequestID return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["request_id"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["request_id"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -45,22 +58,34 @@ public string? Result return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["result"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["result"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } - public CompletedMarkdownifyProperties::Status? Status + public ApiEnum? Status { get { if (!this.Properties.TryGetValue("status", out JsonElement element)) return null; - return JsonSerializer.Deserialize( + return JsonSerializer.Deserialize?>( element, ModelBase.SerializerOptions ); } - set { this.Properties["status"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["status"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? WebsiteURL @@ -72,7 +97,13 @@ public string? WebsiteURL return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["website_url"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["website_url"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override void Validate() diff --git a/src/Scrapegraphai/Models/Markdownify/CompletedMarkdownifyProperties/Status.cs b/src/Scrapegraphai/Models/Markdownify/CompletedMarkdownifyProperties/Status.cs index 120745c..580c705 100644 --- a/src/Scrapegraphai/Models/Markdownify/CompletedMarkdownifyProperties/Status.cs +++ b/src/Scrapegraphai/Models/Markdownify/CompletedMarkdownifyProperties/Status.cs @@ -1,47 +1,49 @@ using System; +using System.Text.Json; using System.Text.Json.Serialization; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.Markdownify.CompletedMarkdownifyProperties; -[JsonConverter(typeof(EnumConverter))] -public sealed record class Status(string value) : IEnum +[JsonConverter(typeof(StatusConverter))] +public enum Status { - public static readonly Status Queued = new("queued"); - - public static readonly Status Processing = new("processing"); - - public static readonly Status Completed = new("completed"); - - readonly string _value = value; + Queued, + Processing, + Completed, +} - public enum Value +sealed class StatusConverter : JsonConverter +{ + public override Status Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) { - Queued, - Processing, - Completed, - } - - public Value Known() => - _value switch + return JsonSerializer.Deserialize(ref reader, options) switch { - "queued" => Value.Queued, - "processing" => Value.Processing, - "completed" => Value.Completed, - _ => throw new ArgumentOutOfRangeException(nameof(_value)), + "queued" => Status.Queued, + "processing" => Status.Processing, + "completed" => Status.Completed, + _ => (Status)(-1), }; - - public string Raw() - { - return _value; - } - - public void Validate() - { - Known(); } - public static Status FromRaw(string value) + public override void Write(Utf8JsonWriter writer, Status value, JsonSerializerOptions options) { - return new(value); + JsonSerializer.Serialize( + writer, + value switch + { + Status.Queued => "queued", + Status.Processing => "processing", + Status.Completed => "completed", + _ => throw new ScrapegraphaiInvalidDataException( + string.Format("Invalid value '{0}' in {1}", value, nameof(value)) + ), + }, + options + ); } } diff --git a/src/Scrapegraphai/Models/Markdownify/MarkdownifyConvertParams.cs b/src/Scrapegraphai/Models/Markdownify/MarkdownifyConvertParams.cs index d7116a1..4a08534 100644 --- a/src/Scrapegraphai/Models/Markdownify/MarkdownifyConvertParams.cs +++ b/src/Scrapegraphai/Models/Markdownify/MarkdownifyConvertParams.cs @@ -3,6 +3,8 @@ using System.Net.Http; using System.Text; using System.Text.Json; +using Scrapegraphai.Core; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.Markdownify; @@ -21,12 +23,24 @@ public required string WebsiteURL get { if (!this.BodyProperties.TryGetValue("website_url", out JsonElement element)) - throw new ArgumentOutOfRangeException("website_url", "Missing required argument"); + throw new ScrapegraphaiInvalidDataException( + "'website_url' cannot be null", + new ArgumentOutOfRangeException("website_url", "Missing required argument") + ); return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions) - ?? throw new ArgumentNullException("website_url"); + ?? throw new ScrapegraphaiInvalidDataException( + "'website_url' cannot be null", + new ArgumentNullException("website_url") + ); + } + set + { + this.BodyProperties["website_url"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); } - set { this.BodyProperties["website_url"] = JsonSerializer.SerializeToElement(value); } } public Dictionary? Headers @@ -41,7 +55,13 @@ public Dictionary? Headers ModelBase.SerializerOptions ); } - set { this.BodyProperties["headers"] = JsonSerializer.SerializeToElement(value); } + set + { + this.BodyProperties["headers"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -56,7 +76,13 @@ public List? Steps return JsonSerializer.Deserialize?>(element, ModelBase.SerializerOptions); } - set { this.BodyProperties["steps"] = JsonSerializer.SerializeToElement(value); } + set + { + this.BodyProperties["steps"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override Uri Url(IScrapegraphaiClient client) @@ -67,7 +93,7 @@ public override Uri Url(IScrapegraphaiClient client) }.Uri; } - public StringContent BodyContent() + internal override StringContent? BodyContent() { return new( JsonSerializer.Serialize(this.BodyProperties), @@ -76,7 +102,10 @@ public StringContent BodyContent() ); } - public void AddHeadersToRequest(HttpRequestMessage request, IScrapegraphaiClient client) + internal override void AddHeadersToRequest( + HttpRequestMessage request, + IScrapegraphaiClient client + ) { ParamsBase.AddDefaultHeaders(request, client); foreach (var item in this.HeaderProperties) diff --git a/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusParams.cs b/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusParams.cs index d644411..f72aace 100644 --- a/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusParams.cs +++ b/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusParams.cs @@ -1,5 +1,6 @@ using System; using System.Net.Http; +using Scrapegraphai.Core; namespace Scrapegraphai.Models.Markdownify; @@ -21,7 +22,10 @@ public override Uri Url(IScrapegraphaiClient client) }.Uri; } - public void AddHeadersToRequest(HttpRequestMessage request, IScrapegraphaiClient client) + internal override void AddHeadersToRequest( + HttpRequestMessage request, + IScrapegraphaiClient client + ) { ParamsBase.AddDefaultHeaders(request, client); foreach (var item in this.HeaderProperties) diff --git a/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusResponse.cs b/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusResponse.cs index 14cbb10..a48eb78 100644 --- a/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusResponse.cs +++ b/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusResponse.cs @@ -1,20 +1,207 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; using System.Text.Json.Serialization; -using MarkdownifyRetrieveStatusResponseProperties = Scrapegraphai.Models.Markdownify.MarkdownifyRetrieveStatusResponseProperties; -using MarkdownifyRetrieveStatusResponseVariants = Scrapegraphai.Models.Markdownify.MarkdownifyRetrieveStatusResponseVariants; +using Scrapegraphai.Exceptions; +using Scrapegraphai.Models.Markdownify.MarkdownifyRetrieveStatusResponseProperties; namespace Scrapegraphai.Models.Markdownify; -[JsonConverter(typeof(UnionConverter))] -public abstract record class MarkdownifyRetrieveStatusResponse +[JsonConverter(typeof(MarkdownifyRetrieveStatusResponseConverter))] +public record class MarkdownifyRetrieveStatusResponse { - internal MarkdownifyRetrieveStatusResponse() { } + public object Value { get; private init; } - public static implicit operator MarkdownifyRetrieveStatusResponse(CompletedMarkdownify value) => - new MarkdownifyRetrieveStatusResponseVariants::CompletedMarkdownifyVariant(value); + public string? Error + { + get + { + return Match( + completedMarkdownify: (x) => x.Error, + failedMarkdownify: (x) => x.Error + ); + } + } - public static implicit operator MarkdownifyRetrieveStatusResponse( - MarkdownifyRetrieveStatusResponseProperties::FailedMarkdownifyResponse value - ) => new MarkdownifyRetrieveStatusResponseVariants::FailedMarkdownifyResponse(value); + public string? RequestID + { + get + { + return Match( + completedMarkdownify: (x) => x.RequestID, + failedMarkdownify: (x) => x.RequestID + ); + } + } - public abstract void Validate(); + public string? Result + { + get + { + return Match( + completedMarkdownify: (x) => x.Result, + failedMarkdownify: (x) => x.Result + ); + } + } + + public string? WebsiteURL + { + get + { + return Match( + completedMarkdownify: (x) => x.WebsiteURL, + failedMarkdownify: (x) => x.WebsiteURL + ); + } + } + + public MarkdownifyRetrieveStatusResponse(CompletedMarkdownify value) + { + Value = value; + } + + public MarkdownifyRetrieveStatusResponse(FailedMarkdownifyResponse value) + { + Value = value; + } + + MarkdownifyRetrieveStatusResponse(UnknownVariant value) + { + Value = value; + } + + public static MarkdownifyRetrieveStatusResponse CreateUnknownVariant(JsonElement value) + { + return new(new UnknownVariant(value)); + } + + public bool TryPickCompletedMarkdownify([NotNullWhen(true)] out CompletedMarkdownify? value) + { + value = this.Value as CompletedMarkdownify; + return value != null; + } + + public bool TryPickFailedMarkdownify([NotNullWhen(true)] out FailedMarkdownifyResponse? value) + { + value = this.Value as FailedMarkdownifyResponse; + return value != null; + } + + public void Switch( + Action completedMarkdownify, + Action failedMarkdownify + ) + { + switch (this.Value) + { + case CompletedMarkdownify value: + completedMarkdownify(value); + break; + case FailedMarkdownifyResponse value: + failedMarkdownify(value); + break; + default: + throw new ScrapegraphaiInvalidDataException( + "Data did not match any variant of MarkdownifyRetrieveStatusResponse" + ); + } + } + + public T Match( + Func completedMarkdownify, + Func failedMarkdownify + ) + { + return this.Value switch + { + CompletedMarkdownify value => completedMarkdownify(value), + FailedMarkdownifyResponse value => failedMarkdownify(value), + _ => throw new ScrapegraphaiInvalidDataException( + "Data did not match any variant of MarkdownifyRetrieveStatusResponse" + ), + }; + } + + public void Validate() + { + if (this.Value is not UnknownVariant) + { + throw new ScrapegraphaiInvalidDataException( + "Data did not match any variant of MarkdownifyRetrieveStatusResponse" + ); + } + } + + private record struct UnknownVariant(JsonElement value); +} + +sealed class MarkdownifyRetrieveStatusResponseConverter + : JsonConverter +{ + public override MarkdownifyRetrieveStatusResponse? Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) + { + List exceptions = []; + + try + { + var deserialized = JsonSerializer.Deserialize( + ref reader, + options + ); + if (deserialized != null) + { + deserialized.Validate(); + return new MarkdownifyRetrieveStatusResponse(deserialized); + } + } + catch (Exception e) when (e is JsonException || e is ScrapegraphaiInvalidDataException) + { + exceptions.Add( + new ScrapegraphaiInvalidDataException( + "Data does not match union variant 'CompletedMarkdownify'", + e + ) + ); + } + + try + { + var deserialized = JsonSerializer.Deserialize( + ref reader, + options + ); + if (deserialized != null) + { + deserialized.Validate(); + return new MarkdownifyRetrieveStatusResponse(deserialized); + } + } + catch (Exception e) when (e is JsonException || e is ScrapegraphaiInvalidDataException) + { + exceptions.Add( + new ScrapegraphaiInvalidDataException( + "Data does not match union variant 'FailedMarkdownifyResponse'", + e + ) + ); + } + + throw new AggregateException(exceptions); + } + + public override void Write( + Utf8JsonWriter writer, + MarkdownifyRetrieveStatusResponse value, + JsonSerializerOptions options + ) + { + object variant = value.Value; + JsonSerializer.Serialize(writer, variant, options); + } } diff --git a/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusResponseProperties/FailedMarkdownifyResponse.cs b/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusResponseProperties/FailedMarkdownifyResponse.cs index d6c3a9f..10a2b2a 100644 --- a/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusResponseProperties/FailedMarkdownifyResponse.cs +++ b/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusResponseProperties/FailedMarkdownifyResponse.cs @@ -2,7 +2,8 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; -using FailedMarkdownifyResponseProperties = Scrapegraphai.Models.Markdownify.MarkdownifyRetrieveStatusResponseProperties.FailedMarkdownifyResponseProperties; +using Scrapegraphai.Core; +using Scrapegraphai.Models.Markdownify.MarkdownifyRetrieveStatusResponseProperties.FailedMarkdownifyResponseProperties; namespace Scrapegraphai.Models.Markdownify.MarkdownifyRetrieveStatusResponseProperties; @@ -20,7 +21,13 @@ public string? Error return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["error"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["error"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? RequestID @@ -32,7 +39,13 @@ public string? RequestID return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["request_id"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["request_id"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? Result @@ -44,22 +57,34 @@ public string? Result return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["result"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["result"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } - public FailedMarkdownifyResponseProperties::Status? Status + public ApiEnum? Status { get { if (!this.Properties.TryGetValue("status", out JsonElement element)) return null; - return JsonSerializer.Deserialize( + return JsonSerializer.Deserialize?>( element, ModelBase.SerializerOptions ); } - set { this.Properties["status"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["status"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? WebsiteURL @@ -71,7 +96,13 @@ public string? WebsiteURL return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["website_url"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["website_url"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override void Validate() diff --git a/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusResponseProperties/FailedMarkdownifyResponseProperties/Status.cs b/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusResponseProperties/FailedMarkdownifyResponseProperties/Status.cs index 20130f5..d819cbc 100644 --- a/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusResponseProperties/FailedMarkdownifyResponseProperties/Status.cs +++ b/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusResponseProperties/FailedMarkdownifyResponseProperties/Status.cs @@ -1,39 +1,43 @@ using System; +using System.Text.Json; using System.Text.Json.Serialization; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.Markdownify.MarkdownifyRetrieveStatusResponseProperties.FailedMarkdownifyResponseProperties; -[JsonConverter(typeof(EnumConverter))] -public sealed record class Status(string value) : IEnum +[JsonConverter(typeof(StatusConverter))] +public enum Status { - public static readonly Status Failed = new("failed"); - - readonly string _value = value; + Failed, +} - public enum Value +sealed class StatusConverter : JsonConverter +{ + public override Status Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) { - Failed, - } - - public Value Known() => - _value switch + return JsonSerializer.Deserialize(ref reader, options) switch { - "failed" => Value.Failed, - _ => throw new ArgumentOutOfRangeException(nameof(_value)), + "failed" => Status.Failed, + _ => (Status)(-1), }; - - public string Raw() - { - return _value; - } - - public void Validate() - { - Known(); } - public static Status FromRaw(string value) + public override void Write(Utf8JsonWriter writer, Status value, JsonSerializerOptions options) { - return new(value); + JsonSerializer.Serialize( + writer, + value switch + { + Status.Failed => "failed", + _ => throw new ScrapegraphaiInvalidDataException( + string.Format("Invalid value '{0}' in {1}", value, nameof(value)) + ), + }, + options + ); } } diff --git a/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusResponseVariants/All.cs b/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusResponseVariants/All.cs deleted file mode 100644 index 220c593..0000000 --- a/src/Scrapegraphai/Models/Markdownify/MarkdownifyRetrieveStatusResponseVariants/All.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Text.Json.Serialization; -using MarkdownifyRetrieveStatusResponseProperties = Scrapegraphai.Models.Markdownify.MarkdownifyRetrieveStatusResponseProperties; - -namespace Scrapegraphai.Models.Markdownify.MarkdownifyRetrieveStatusResponseVariants; - -[JsonConverter(typeof(VariantConverter))] -public sealed record class CompletedMarkdownifyVariant(CompletedMarkdownify Value) - : MarkdownifyRetrieveStatusResponse, - IVariant -{ - public static CompletedMarkdownifyVariant From(CompletedMarkdownify value) - { - return new(value); - } - - public override void Validate() - { - this.Value.Validate(); - } -} - -[JsonConverter( - typeof(VariantConverter< - FailedMarkdownifyResponse, - MarkdownifyRetrieveStatusResponseProperties::FailedMarkdownifyResponse - >) -)] -public sealed record class FailedMarkdownifyResponse( - MarkdownifyRetrieveStatusResponseProperties::FailedMarkdownifyResponse Value -) - : MarkdownifyRetrieveStatusResponse, - IVariant< - FailedMarkdownifyResponse, - MarkdownifyRetrieveStatusResponseProperties::FailedMarkdownifyResponse - > -{ - public static FailedMarkdownifyResponse From( - MarkdownifyRetrieveStatusResponseProperties::FailedMarkdownifyResponse value - ) - { - return new(value); - } - - public override void Validate() - { - this.Value.Validate(); - } -} diff --git a/src/Scrapegraphai/Models/Searchscraper/CompletedSearchScraper.cs b/src/Scrapegraphai/Models/Searchscraper/CompletedSearchScraper.cs index afc1c90..557f8f4 100644 --- a/src/Scrapegraphai/Models/Searchscraper/CompletedSearchScraper.cs +++ b/src/Scrapegraphai/Models/Searchscraper/CompletedSearchScraper.cs @@ -2,7 +2,8 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; -using CompletedSearchScraperProperties = Scrapegraphai.Models.Searchscraper.CompletedSearchScraperProperties; +using Scrapegraphai.Core; +using Scrapegraphai.Models.Searchscraper.CompletedSearchScraperProperties; namespace Scrapegraphai.Models.Searchscraper; @@ -18,7 +19,13 @@ public string? Error return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["error"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["error"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public long? NumResults @@ -30,7 +37,13 @@ public long? NumResults return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["num_results"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["num_results"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -45,7 +58,13 @@ public List? ReferenceURLs return JsonSerializer.Deserialize?>(element, ModelBase.SerializerOptions); } - set { this.Properties["reference_urls"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["reference_urls"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? RequestID @@ -57,7 +76,13 @@ public string? RequestID return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["request_id"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["request_id"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -72,22 +97,34 @@ public JsonElement? Result return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["result"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["result"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } - public CompletedSearchScraperProperties::Status? Status + public ApiEnum? Status { get { if (!this.Properties.TryGetValue("status", out JsonElement element)) return null; - return JsonSerializer.Deserialize( + return JsonSerializer.Deserialize?>( element, ModelBase.SerializerOptions ); } - set { this.Properties["status"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["status"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? UserPrompt @@ -99,7 +136,13 @@ public string? UserPrompt return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["user_prompt"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["user_prompt"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override void Validate() diff --git a/src/Scrapegraphai/Models/Searchscraper/CompletedSearchScraperProperties/Status.cs b/src/Scrapegraphai/Models/Searchscraper/CompletedSearchScraperProperties/Status.cs index 30eca60..b7030d3 100644 --- a/src/Scrapegraphai/Models/Searchscraper/CompletedSearchScraperProperties/Status.cs +++ b/src/Scrapegraphai/Models/Searchscraper/CompletedSearchScraperProperties/Status.cs @@ -1,47 +1,49 @@ using System; +using System.Text.Json; using System.Text.Json.Serialization; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.Searchscraper.CompletedSearchScraperProperties; -[JsonConverter(typeof(EnumConverter))] -public sealed record class Status(string value) : IEnum +[JsonConverter(typeof(StatusConverter))] +public enum Status { - public static readonly Status Queued = new("queued"); - - public static readonly Status Processing = new("processing"); - - public static readonly Status Completed = new("completed"); - - readonly string _value = value; + Queued, + Processing, + Completed, +} - public enum Value +sealed class StatusConverter : JsonConverter +{ + public override Status Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) { - Queued, - Processing, - Completed, - } - - public Value Known() => - _value switch + return JsonSerializer.Deserialize(ref reader, options) switch { - "queued" => Value.Queued, - "processing" => Value.Processing, - "completed" => Value.Completed, - _ => throw new ArgumentOutOfRangeException(nameof(_value)), + "queued" => Status.Queued, + "processing" => Status.Processing, + "completed" => Status.Completed, + _ => (Status)(-1), }; - - public string Raw() - { - return _value; - } - - public void Validate() - { - Known(); } - public static Status FromRaw(string value) + public override void Write(Utf8JsonWriter writer, Status value, JsonSerializerOptions options) { - return new(value); + JsonSerializer.Serialize( + writer, + value switch + { + Status.Queued => "queued", + Status.Processing => "processing", + Status.Completed => "completed", + _ => throw new ScrapegraphaiInvalidDataException( + string.Format("Invalid value '{0}' in {1}", value, nameof(value)) + ), + }, + options + ); } } diff --git a/src/Scrapegraphai/Models/Searchscraper/SearchscraperCreateParams.cs b/src/Scrapegraphai/Models/Searchscraper/SearchscraperCreateParams.cs index bd23365..f98bb84 100644 --- a/src/Scrapegraphai/Models/Searchscraper/SearchscraperCreateParams.cs +++ b/src/Scrapegraphai/Models/Searchscraper/SearchscraperCreateParams.cs @@ -3,6 +3,8 @@ using System.Net.Http; using System.Text; using System.Text.Json; +using Scrapegraphai.Core; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.Searchscraper; @@ -23,12 +25,24 @@ public required string UserPrompt get { if (!this.BodyProperties.TryGetValue("user_prompt", out JsonElement element)) - throw new ArgumentOutOfRangeException("user_prompt", "Missing required argument"); + throw new ScrapegraphaiInvalidDataException( + "'user_prompt' cannot be null", + new ArgumentOutOfRangeException("user_prompt", "Missing required argument") + ); return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions) - ?? throw new ArgumentNullException("user_prompt"); + ?? throw new ScrapegraphaiInvalidDataException( + "'user_prompt' cannot be null", + new ArgumentNullException("user_prompt") + ); + } + set + { + this.BodyProperties["user_prompt"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); } - set { this.BodyProperties["user_prompt"] = JsonSerializer.SerializeToElement(value); } } public Dictionary? Headers @@ -43,7 +57,13 @@ public Dictionary? Headers ModelBase.SerializerOptions ); } - set { this.BodyProperties["headers"] = JsonSerializer.SerializeToElement(value); } + set + { + this.BodyProperties["headers"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -58,7 +78,13 @@ public long? NumResults return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.BodyProperties["num_results"] = JsonSerializer.SerializeToElement(value); } + set + { + this.BodyProperties["num_results"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -73,7 +99,13 @@ public JsonElement? OutputSchema return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.BodyProperties["output_schema"] = JsonSerializer.SerializeToElement(value); } + set + { + this.BodyProperties["output_schema"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override Uri Url(IScrapegraphaiClient client) @@ -84,7 +116,7 @@ public override Uri Url(IScrapegraphaiClient client) }.Uri; } - public StringContent BodyContent() + internal override StringContent? BodyContent() { return new( JsonSerializer.Serialize(this.BodyProperties), @@ -93,7 +125,10 @@ public StringContent BodyContent() ); } - public void AddHeadersToRequest(HttpRequestMessage request, IScrapegraphaiClient client) + internal override void AddHeadersToRequest( + HttpRequestMessage request, + IScrapegraphaiClient client + ) { ParamsBase.AddDefaultHeaders(request, client); foreach (var item in this.HeaderProperties) diff --git a/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusParams.cs b/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusParams.cs index a7f4d89..858b969 100644 --- a/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusParams.cs +++ b/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusParams.cs @@ -1,5 +1,6 @@ using System; using System.Net.Http; +using Scrapegraphai.Core; namespace Scrapegraphai.Models.Searchscraper; @@ -21,7 +22,10 @@ public override Uri Url(IScrapegraphaiClient client) }.Uri; } - public void AddHeadersToRequest(HttpRequestMessage request, IScrapegraphaiClient client) + internal override void AddHeadersToRequest( + HttpRequestMessage request, + IScrapegraphaiClient client + ) { ParamsBase.AddDefaultHeaders(request, client); foreach (var item in this.HeaderProperties) diff --git a/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusResponse.cs b/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusResponse.cs index fa4cd94..d01735b 100644 --- a/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusResponse.cs +++ b/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusResponse.cs @@ -1,21 +1,220 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; using System.Text.Json.Serialization; -using SearchscraperRetrieveStatusResponseProperties = Scrapegraphai.Models.Searchscraper.SearchscraperRetrieveStatusResponseProperties; -using SearchscraperRetrieveStatusResponseVariants = Scrapegraphai.Models.Searchscraper.SearchscraperRetrieveStatusResponseVariants; +using Scrapegraphai.Exceptions; +using Scrapegraphai.Models.Searchscraper.SearchscraperRetrieveStatusResponseProperties; namespace Scrapegraphai.Models.Searchscraper; -[JsonConverter(typeof(UnionConverter))] -public abstract record class SearchscraperRetrieveStatusResponse +[JsonConverter(typeof(SearchscraperRetrieveStatusResponseConverter))] +public record class SearchscraperRetrieveStatusResponse { - internal SearchscraperRetrieveStatusResponse() { } + public object Value { get; private init; } - public static implicit operator SearchscraperRetrieveStatusResponse( - CompletedSearchScraper value - ) => new SearchscraperRetrieveStatusResponseVariants::CompletedSearchScraperVariant(value); + public string? Error + { + get + { + return Match( + completedSearchScraper: (x) => x.Error, + failedSearchScraper: (x) => x.Error + ); + } + } - public static implicit operator SearchscraperRetrieveStatusResponse( - SearchscraperRetrieveStatusResponseProperties::FailedSearchScraperResponse value - ) => new SearchscraperRetrieveStatusResponseVariants::FailedSearchScraperResponse(value); + public long? NumResults + { + get + { + return Match( + completedSearchScraper: (x) => x.NumResults, + failedSearchScraper: (x) => x.NumResults + ); + } + } - public abstract void Validate(); + public string? RequestID + { + get + { + return Match( + completedSearchScraper: (x) => x.RequestID, + failedSearchScraper: (x) => x.RequestID + ); + } + } + + public JsonElement? Result + { + get + { + return Match( + completedSearchScraper: (x) => x.Result, + failedSearchScraper: (x) => x.Result + ); + } + } + + public string? UserPrompt + { + get + { + return Match( + completedSearchScraper: (x) => x.UserPrompt, + failedSearchScraper: (x) => x.UserPrompt + ); + } + } + + public SearchscraperRetrieveStatusResponse(CompletedSearchScraper value) + { + Value = value; + } + + public SearchscraperRetrieveStatusResponse(FailedSearchScraperResponse value) + { + Value = value; + } + + SearchscraperRetrieveStatusResponse(UnknownVariant value) + { + Value = value; + } + + public static SearchscraperRetrieveStatusResponse CreateUnknownVariant(JsonElement value) + { + return new(new UnknownVariant(value)); + } + + public bool TryPickCompletedSearchScraper([NotNullWhen(true)] out CompletedSearchScraper? value) + { + value = this.Value as CompletedSearchScraper; + return value != null; + } + + public bool TryPickFailedSearchScraper( + [NotNullWhen(true)] out FailedSearchScraperResponse? value + ) + { + value = this.Value as FailedSearchScraperResponse; + return value != null; + } + + public void Switch( + Action completedSearchScraper, + Action failedSearchScraper + ) + { + switch (this.Value) + { + case CompletedSearchScraper value: + completedSearchScraper(value); + break; + case FailedSearchScraperResponse value: + failedSearchScraper(value); + break; + default: + throw new ScrapegraphaiInvalidDataException( + "Data did not match any variant of SearchscraperRetrieveStatusResponse" + ); + } + } + + public T Match( + Func completedSearchScraper, + Func failedSearchScraper + ) + { + return this.Value switch + { + CompletedSearchScraper value => completedSearchScraper(value), + FailedSearchScraperResponse value => failedSearchScraper(value), + _ => throw new ScrapegraphaiInvalidDataException( + "Data did not match any variant of SearchscraperRetrieveStatusResponse" + ), + }; + } + + public void Validate() + { + if (this.Value is not UnknownVariant) + { + throw new ScrapegraphaiInvalidDataException( + "Data did not match any variant of SearchscraperRetrieveStatusResponse" + ); + } + } + + private record struct UnknownVariant(JsonElement value); +} + +sealed class SearchscraperRetrieveStatusResponseConverter + : JsonConverter +{ + public override SearchscraperRetrieveStatusResponse? Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) + { + List exceptions = []; + + try + { + var deserialized = JsonSerializer.Deserialize( + ref reader, + options + ); + if (deserialized != null) + { + deserialized.Validate(); + return new SearchscraperRetrieveStatusResponse(deserialized); + } + } + catch (Exception e) when (e is JsonException || e is ScrapegraphaiInvalidDataException) + { + exceptions.Add( + new ScrapegraphaiInvalidDataException( + "Data does not match union variant 'CompletedSearchScraper'", + e + ) + ); + } + + try + { + var deserialized = JsonSerializer.Deserialize( + ref reader, + options + ); + if (deserialized != null) + { + deserialized.Validate(); + return new SearchscraperRetrieveStatusResponse(deserialized); + } + } + catch (Exception e) when (e is JsonException || e is ScrapegraphaiInvalidDataException) + { + exceptions.Add( + new ScrapegraphaiInvalidDataException( + "Data does not match union variant 'FailedSearchScraperResponse'", + e + ) + ); + } + + throw new AggregateException(exceptions); + } + + public override void Write( + Utf8JsonWriter writer, + SearchscraperRetrieveStatusResponse value, + JsonSerializerOptions options + ) + { + object variant = value.Value; + JsonSerializer.Serialize(writer, variant, options); + } } diff --git a/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusResponseProperties/FailedSearchScraperResponse.cs b/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusResponseProperties/FailedSearchScraperResponse.cs index a851e8c..2bb410e 100644 --- a/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusResponseProperties/FailedSearchScraperResponse.cs +++ b/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusResponseProperties/FailedSearchScraperResponse.cs @@ -2,7 +2,8 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; -using FailedSearchScraperResponseProperties = Scrapegraphai.Models.Searchscraper.SearchscraperRetrieveStatusResponseProperties.FailedSearchScraperResponseProperties; +using Scrapegraphai.Core; +using Scrapegraphai.Models.Searchscraper.SearchscraperRetrieveStatusResponseProperties.FailedSearchScraperResponseProperties; namespace Scrapegraphai.Models.Searchscraper.SearchscraperRetrieveStatusResponseProperties; @@ -20,7 +21,13 @@ public string? Error return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["error"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["error"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public long? NumResults @@ -32,7 +39,13 @@ public long? NumResults return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["num_results"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["num_results"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public List? ReferenceURLs @@ -44,7 +57,13 @@ public List? ReferenceURLs return JsonSerializer.Deserialize?>(element, ModelBase.SerializerOptions); } - set { this.Properties["reference_urls"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["reference_urls"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? RequestID @@ -56,7 +75,13 @@ public string? RequestID return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["request_id"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["request_id"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public JsonElement? Result @@ -68,22 +93,34 @@ public JsonElement? Result return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["result"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["result"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } - public FailedSearchScraperResponseProperties::Status? Status + public ApiEnum? Status { get { if (!this.Properties.TryGetValue("status", out JsonElement element)) return null; - return JsonSerializer.Deserialize( + return JsonSerializer.Deserialize?>( element, ModelBase.SerializerOptions ); } - set { this.Properties["status"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["status"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? UserPrompt @@ -95,7 +132,13 @@ public string? UserPrompt return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["user_prompt"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["user_prompt"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override void Validate() diff --git a/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusResponseProperties/FailedSearchScraperResponseProperties/Status.cs b/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusResponseProperties/FailedSearchScraperResponseProperties/Status.cs index 90d596e..35572ef 100644 --- a/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusResponseProperties/FailedSearchScraperResponseProperties/Status.cs +++ b/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusResponseProperties/FailedSearchScraperResponseProperties/Status.cs @@ -1,39 +1,43 @@ using System; +using System.Text.Json; using System.Text.Json.Serialization; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.Searchscraper.SearchscraperRetrieveStatusResponseProperties.FailedSearchScraperResponseProperties; -[JsonConverter(typeof(EnumConverter))] -public sealed record class Status(string value) : IEnum +[JsonConverter(typeof(StatusConverter))] +public enum Status { - public static readonly Status Failed = new("failed"); - - readonly string _value = value; + Failed, +} - public enum Value +sealed class StatusConverter : JsonConverter +{ + public override Status Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) { - Failed, - } - - public Value Known() => - _value switch + return JsonSerializer.Deserialize(ref reader, options) switch { - "failed" => Value.Failed, - _ => throw new ArgumentOutOfRangeException(nameof(_value)), + "failed" => Status.Failed, + _ => (Status)(-1), }; - - public string Raw() - { - return _value; - } - - public void Validate() - { - Known(); } - public static Status FromRaw(string value) + public override void Write(Utf8JsonWriter writer, Status value, JsonSerializerOptions options) { - return new(value); + JsonSerializer.Serialize( + writer, + value switch + { + Status.Failed => "failed", + _ => throw new ScrapegraphaiInvalidDataException( + string.Format("Invalid value '{0}' in {1}", value, nameof(value)) + ), + }, + options + ); } } diff --git a/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusResponseVariants/All.cs b/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusResponseVariants/All.cs deleted file mode 100644 index 0c442eb..0000000 --- a/src/Scrapegraphai/Models/Searchscraper/SearchscraperRetrieveStatusResponseVariants/All.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Text.Json.Serialization; -using SearchscraperRetrieveStatusResponseProperties = Scrapegraphai.Models.Searchscraper.SearchscraperRetrieveStatusResponseProperties; - -namespace Scrapegraphai.Models.Searchscraper.SearchscraperRetrieveStatusResponseVariants; - -[JsonConverter(typeof(VariantConverter))] -public sealed record class CompletedSearchScraperVariant(CompletedSearchScraper Value) - : SearchscraperRetrieveStatusResponse, - IVariant -{ - public static CompletedSearchScraperVariant From(CompletedSearchScraper value) - { - return new(value); - } - - public override void Validate() - { - this.Value.Validate(); - } -} - -[JsonConverter( - typeof(VariantConverter< - FailedSearchScraperResponse, - SearchscraperRetrieveStatusResponseProperties::FailedSearchScraperResponse - >) -)] -public sealed record class FailedSearchScraperResponse( - SearchscraperRetrieveStatusResponseProperties::FailedSearchScraperResponse Value -) - : SearchscraperRetrieveStatusResponse, - IVariant< - FailedSearchScraperResponse, - SearchscraperRetrieveStatusResponseProperties::FailedSearchScraperResponse - > -{ - public static FailedSearchScraperResponse From( - SearchscraperRetrieveStatusResponseProperties::FailedSearchScraperResponse value - ) - { - return new(value); - } - - public override void Validate() - { - this.Value.Validate(); - } -} diff --git a/src/Scrapegraphai/Models/Smartscraper/CompletedSmartscraper.cs b/src/Scrapegraphai/Models/Smartscraper/CompletedSmartscraper.cs index 0a92304..5cd2b5e 100644 --- a/src/Scrapegraphai/Models/Smartscraper/CompletedSmartscraper.cs +++ b/src/Scrapegraphai/Models/Smartscraper/CompletedSmartscraper.cs @@ -2,7 +2,8 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; -using CompletedSmartscraperProperties = Scrapegraphai.Models.Smartscraper.CompletedSmartscraperProperties; +using Scrapegraphai.Core; +using Scrapegraphai.Models.Smartscraper.CompletedSmartscraperProperties; namespace Scrapegraphai.Models.Smartscraper; @@ -21,7 +22,13 @@ public string? Error return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["error"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["error"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -36,7 +43,13 @@ public string? RequestID return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["request_id"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["request_id"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -51,25 +64,37 @@ public JsonElement? Result return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["result"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["result"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// /// Processing status /// - public CompletedSmartscraperProperties::Status? Status + public ApiEnum? Status { get { if (!this.Properties.TryGetValue("status", out JsonElement element)) return null; - return JsonSerializer.Deserialize( + return JsonSerializer.Deserialize?>( element, ModelBase.SerializerOptions ); } - set { this.Properties["status"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["status"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? UserPrompt @@ -81,7 +106,13 @@ public string? UserPrompt return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["user_prompt"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["user_prompt"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? WebsiteURL @@ -93,7 +124,13 @@ public string? WebsiteURL return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["website_url"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["website_url"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override void Validate() diff --git a/src/Scrapegraphai/Models/Smartscraper/CompletedSmartscraperProperties/Status.cs b/src/Scrapegraphai/Models/Smartscraper/CompletedSmartscraperProperties/Status.cs index 4bf36cb..3b0d148 100644 --- a/src/Scrapegraphai/Models/Smartscraper/CompletedSmartscraperProperties/Status.cs +++ b/src/Scrapegraphai/Models/Smartscraper/CompletedSmartscraperProperties/Status.cs @@ -1,50 +1,52 @@ using System; +using System.Text.Json; using System.Text.Json.Serialization; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.Smartscraper.CompletedSmartscraperProperties; /// /// Processing status /// -[JsonConverter(typeof(EnumConverter))] -public sealed record class Status(string value) : IEnum +[JsonConverter(typeof(StatusConverter))] +public enum Status { - public static readonly Status Queued = new("queued"); - - public static readonly Status Processing = new("processing"); - - public static readonly Status Completed = new("completed"); - - readonly string _value = value; + Queued, + Processing, + Completed, +} - public enum Value +sealed class StatusConverter : JsonConverter +{ + public override Status Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) { - Queued, - Processing, - Completed, - } - - public Value Known() => - _value switch + return JsonSerializer.Deserialize(ref reader, options) switch { - "queued" => Value.Queued, - "processing" => Value.Processing, - "completed" => Value.Completed, - _ => throw new ArgumentOutOfRangeException(nameof(_value)), + "queued" => Status.Queued, + "processing" => Status.Processing, + "completed" => Status.Completed, + _ => (Status)(-1), }; - - public string Raw() - { - return _value; - } - - public void Validate() - { - Known(); } - public static Status FromRaw(string value) + public override void Write(Utf8JsonWriter writer, Status value, JsonSerializerOptions options) { - return new(value); + JsonSerializer.Serialize( + writer, + value switch + { + Status.Queued => "queued", + Status.Processing => "processing", + Status.Completed => "completed", + _ => throw new ScrapegraphaiInvalidDataException( + string.Format("Invalid value '{0}' in {1}", value, nameof(value)) + ), + }, + options + ); } } diff --git a/src/Scrapegraphai/Models/Smartscraper/FailedSmartscraper.cs b/src/Scrapegraphai/Models/Smartscraper/FailedSmartscraper.cs index 0b05778..1ce23ab 100644 --- a/src/Scrapegraphai/Models/Smartscraper/FailedSmartscraper.cs +++ b/src/Scrapegraphai/Models/Smartscraper/FailedSmartscraper.cs @@ -2,7 +2,8 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; -using FailedSmartscraperProperties = Scrapegraphai.Models.Smartscraper.FailedSmartscraperProperties; +using Scrapegraphai.Core; +using Scrapegraphai.Models.Smartscraper.FailedSmartscraperProperties; namespace Scrapegraphai.Models.Smartscraper; @@ -21,7 +22,13 @@ public string? Error return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["error"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["error"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? RequestID @@ -33,7 +40,13 @@ public string? RequestID return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["request_id"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["request_id"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public JsonElement? Result @@ -45,22 +58,34 @@ public JsonElement? Result return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["result"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["result"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } - public FailedSmartscraperProperties::Status? Status + public ApiEnum? Status { get { if (!this.Properties.TryGetValue("status", out JsonElement element)) return null; - return JsonSerializer.Deserialize( + return JsonSerializer.Deserialize?>( element, ModelBase.SerializerOptions ); } - set { this.Properties["status"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["status"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? UserPrompt @@ -72,7 +97,13 @@ public string? UserPrompt return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["user_prompt"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["user_prompt"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public string? WebsiteURL @@ -84,7 +115,13 @@ public string? WebsiteURL return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["website_url"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["website_url"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override void Validate() diff --git a/src/Scrapegraphai/Models/Smartscraper/FailedSmartscraperProperties/Status.cs b/src/Scrapegraphai/Models/Smartscraper/FailedSmartscraperProperties/Status.cs index f38c89f..8dbcab4 100644 --- a/src/Scrapegraphai/Models/Smartscraper/FailedSmartscraperProperties/Status.cs +++ b/src/Scrapegraphai/Models/Smartscraper/FailedSmartscraperProperties/Status.cs @@ -1,39 +1,43 @@ using System; +using System.Text.Json; using System.Text.Json.Serialization; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.Smartscraper.FailedSmartscraperProperties; -[JsonConverter(typeof(EnumConverter))] -public sealed record class Status(string value) : IEnum +[JsonConverter(typeof(StatusConverter))] +public enum Status { - public static readonly Status Failed = new("failed"); - - readonly string _value = value; + Failed, +} - public enum Value +sealed class StatusConverter : JsonConverter +{ + public override Status Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) { - Failed, - } - - public Value Known() => - _value switch + return JsonSerializer.Deserialize(ref reader, options) switch { - "failed" => Value.Failed, - _ => throw new ArgumentOutOfRangeException(nameof(_value)), + "failed" => Status.Failed, + _ => (Status)(-1), }; - - public string Raw() - { - return _value; - } - - public void Validate() - { - Known(); } - public static Status FromRaw(string value) + public override void Write(Utf8JsonWriter writer, Status value, JsonSerializerOptions options) { - return new(value); + JsonSerializer.Serialize( + writer, + value switch + { + Status.Failed => "failed", + _ => throw new ScrapegraphaiInvalidDataException( + string.Format("Invalid value '{0}' in {1}", value, nameof(value)) + ), + }, + options + ); } } diff --git a/src/Scrapegraphai/Models/Smartscraper/SmartscraperCreateParams.cs b/src/Scrapegraphai/Models/Smartscraper/SmartscraperCreateParams.cs index ef8e33e..424e715 100644 --- a/src/Scrapegraphai/Models/Smartscraper/SmartscraperCreateParams.cs +++ b/src/Scrapegraphai/Models/Smartscraper/SmartscraperCreateParams.cs @@ -3,6 +3,8 @@ using System.Net.Http; using System.Text; using System.Text.Json; +using Scrapegraphai.Core; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.Smartscraper; @@ -22,12 +24,24 @@ public required string UserPrompt get { if (!this.BodyProperties.TryGetValue("user_prompt", out JsonElement element)) - throw new ArgumentOutOfRangeException("user_prompt", "Missing required argument"); + throw new ScrapegraphaiInvalidDataException( + "'user_prompt' cannot be null", + new ArgumentOutOfRangeException("user_prompt", "Missing required argument") + ); return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions) - ?? throw new ArgumentNullException("user_prompt"); + ?? throw new ScrapegraphaiInvalidDataException( + "'user_prompt' cannot be null", + new ArgumentNullException("user_prompt") + ); + } + set + { + this.BodyProperties["user_prompt"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); } - set { this.BodyProperties["user_prompt"] = JsonSerializer.SerializeToElement(value); } } /// @@ -45,7 +59,13 @@ public Dictionary? Cookies ModelBase.SerializerOptions ); } - set { this.BodyProperties["cookies"] = JsonSerializer.SerializeToElement(value); } + set + { + this.BodyProperties["cookies"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -63,7 +83,13 @@ public Dictionary? Headers ModelBase.SerializerOptions ); } - set { this.BodyProperties["headers"] = JsonSerializer.SerializeToElement(value); } + set + { + this.BodyProperties["headers"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -78,7 +104,13 @@ public long? NumberOfScrolls return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.BodyProperties["number_of_scrolls"] = JsonSerializer.SerializeToElement(value); } + set + { + this.BodyProperties["number_of_scrolls"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -93,7 +125,13 @@ public JsonElement? OutputSchema return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.BodyProperties["output_schema"] = JsonSerializer.SerializeToElement(value); } + set + { + this.BodyProperties["output_schema"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -108,7 +146,13 @@ public bool? RenderHeavyJs return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.BodyProperties["render_heavy_js"] = JsonSerializer.SerializeToElement(value); } + set + { + this.BodyProperties["render_heavy_js"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -123,7 +167,13 @@ public List? Steps return JsonSerializer.Deserialize?>(element, ModelBase.SerializerOptions); } - set { this.BodyProperties["steps"] = JsonSerializer.SerializeToElement(value); } + set + { + this.BodyProperties["steps"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -138,7 +188,13 @@ public long? TotalPages return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.BodyProperties["total_pages"] = JsonSerializer.SerializeToElement(value); } + set + { + this.BodyProperties["total_pages"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -153,7 +209,13 @@ public string? WebsiteHTML return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.BodyProperties["website_html"] = JsonSerializer.SerializeToElement(value); } + set + { + this.BodyProperties["website_html"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } /// @@ -168,7 +230,13 @@ public string? WebsiteURL return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.BodyProperties["website_url"] = JsonSerializer.SerializeToElement(value); } + set + { + this.BodyProperties["website_url"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override Uri Url(IScrapegraphaiClient client) @@ -179,7 +247,7 @@ public override Uri Url(IScrapegraphaiClient client) }.Uri; } - public StringContent BodyContent() + internal override StringContent? BodyContent() { return new( JsonSerializer.Serialize(this.BodyProperties), @@ -188,7 +256,10 @@ public StringContent BodyContent() ); } - public void AddHeadersToRequest(HttpRequestMessage request, IScrapegraphaiClient client) + internal override void AddHeadersToRequest( + HttpRequestMessage request, + IScrapegraphaiClient client + ) { ParamsBase.AddDefaultHeaders(request, client); foreach (var item in this.HeaderProperties) diff --git a/src/Scrapegraphai/Models/Smartscraper/SmartscraperListParams.cs b/src/Scrapegraphai/Models/Smartscraper/SmartscraperListParams.cs index 01727b5..7b83f44 100644 --- a/src/Scrapegraphai/Models/Smartscraper/SmartscraperListParams.cs +++ b/src/Scrapegraphai/Models/Smartscraper/SmartscraperListParams.cs @@ -1,5 +1,6 @@ using System; using System.Net.Http; +using Scrapegraphai.Core; namespace Scrapegraphai.Models.Smartscraper; @@ -16,7 +17,10 @@ public override Uri Url(IScrapegraphaiClient client) }.Uri; } - public void AddHeadersToRequest(HttpRequestMessage request, IScrapegraphaiClient client) + internal override void AddHeadersToRequest( + HttpRequestMessage request, + IScrapegraphaiClient client + ) { ParamsBase.AddDefaultHeaders(request, client); foreach (var item in this.HeaderProperties) diff --git a/src/Scrapegraphai/Models/Smartscraper/SmartscraperListResponse.cs b/src/Scrapegraphai/Models/Smartscraper/SmartscraperListResponse.cs index 1797ed7..3b0cbb3 100644 --- a/src/Scrapegraphai/Models/Smartscraper/SmartscraperListResponse.cs +++ b/src/Scrapegraphai/Models/Smartscraper/SmartscraperListResponse.cs @@ -1,18 +1,213 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; using System.Text.Json.Serialization; -using SmartscraperListResponseVariants = Scrapegraphai.Models.Smartscraper.SmartscraperListResponseVariants; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.Smartscraper; -[JsonConverter(typeof(UnionConverter))] -public abstract record class SmartscraperListResponse +[JsonConverter(typeof(SmartscraperListResponseConverter))] +public record class SmartscraperListResponse { - internal SmartscraperListResponse() { } + public object Value { get; private init; } - public static implicit operator SmartscraperListResponse(CompletedSmartscraper value) => - new SmartscraperListResponseVariants::CompletedSmartscraperVariant(value); + public string? Error + { + get + { + return Match( + completedSmartscraper: (x) => x.Error, + failedSmartscraper: (x) => x.Error + ); + } + } - public static implicit operator SmartscraperListResponse(FailedSmartscraper value) => - new SmartscraperListResponseVariants::FailedSmartscraperVariant(value); + public string? RequestID + { + get + { + return Match( + completedSmartscraper: (x) => x.RequestID, + failedSmartscraper: (x) => x.RequestID + ); + } + } - public abstract void Validate(); + public JsonElement? Result + { + get + { + return Match( + completedSmartscraper: (x) => x.Result, + failedSmartscraper: (x) => x.Result + ); + } + } + + public string? UserPrompt + { + get + { + return Match( + completedSmartscraper: (x) => x.UserPrompt, + failedSmartscraper: (x) => x.UserPrompt + ); + } + } + + public string? WebsiteURL + { + get + { + return Match( + completedSmartscraper: (x) => x.WebsiteURL, + failedSmartscraper: (x) => x.WebsiteURL + ); + } + } + + public SmartscraperListResponse(CompletedSmartscraper value) + { + Value = value; + } + + public SmartscraperListResponse(FailedSmartscraper value) + { + Value = value; + } + + SmartscraperListResponse(UnknownVariant value) + { + Value = value; + } + + public static SmartscraperListResponse CreateUnknownVariant(JsonElement value) + { + return new(new UnknownVariant(value)); + } + + public bool TryPickCompletedSmartscraper([NotNullWhen(true)] out CompletedSmartscraper? value) + { + value = this.Value as CompletedSmartscraper; + return value != null; + } + + public bool TryPickFailedSmartscraper([NotNullWhen(true)] out FailedSmartscraper? value) + { + value = this.Value as FailedSmartscraper; + return value != null; + } + + public void Switch( + Action completedSmartscraper, + Action failedSmartscraper + ) + { + switch (this.Value) + { + case CompletedSmartscraper value: + completedSmartscraper(value); + break; + case FailedSmartscraper value: + failedSmartscraper(value); + break; + default: + throw new ScrapegraphaiInvalidDataException( + "Data did not match any variant of SmartscraperListResponse" + ); + } + } + + public T Match( + Func completedSmartscraper, + Func failedSmartscraper + ) + { + return this.Value switch + { + CompletedSmartscraper value => completedSmartscraper(value), + FailedSmartscraper value => failedSmartscraper(value), + _ => throw new ScrapegraphaiInvalidDataException( + "Data did not match any variant of SmartscraperListResponse" + ), + }; + } + + public void Validate() + { + if (this.Value is not UnknownVariant) + { + throw new ScrapegraphaiInvalidDataException( + "Data did not match any variant of SmartscraperListResponse" + ); + } + } + + private record struct UnknownVariant(JsonElement value); +} + +sealed class SmartscraperListResponseConverter : JsonConverter +{ + public override SmartscraperListResponse? Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) + { + List exceptions = []; + + try + { + var deserialized = JsonSerializer.Deserialize( + ref reader, + options + ); + if (deserialized != null) + { + deserialized.Validate(); + return new SmartscraperListResponse(deserialized); + } + } + catch (Exception e) when (e is JsonException || e is ScrapegraphaiInvalidDataException) + { + exceptions.Add( + new ScrapegraphaiInvalidDataException( + "Data does not match union variant 'CompletedSmartscraper'", + e + ) + ); + } + + try + { + var deserialized = JsonSerializer.Deserialize(ref reader, options); + if (deserialized != null) + { + deserialized.Validate(); + return new SmartscraperListResponse(deserialized); + } + } + catch (Exception e) when (e is JsonException || e is ScrapegraphaiInvalidDataException) + { + exceptions.Add( + new ScrapegraphaiInvalidDataException( + "Data does not match union variant 'FailedSmartscraper'", + e + ) + ); + } + + throw new AggregateException(exceptions); + } + + public override void Write( + Utf8JsonWriter writer, + SmartscraperListResponse value, + JsonSerializerOptions options + ) + { + object variant = value.Value; + JsonSerializer.Serialize(writer, variant, options); + } } diff --git a/src/Scrapegraphai/Models/Smartscraper/SmartscraperListResponseVariants/All.cs b/src/Scrapegraphai/Models/Smartscraper/SmartscraperListResponseVariants/All.cs deleted file mode 100644 index 5ccc0fa..0000000 --- a/src/Scrapegraphai/Models/Smartscraper/SmartscraperListResponseVariants/All.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Text.Json.Serialization; - -namespace Scrapegraphai.Models.Smartscraper.SmartscraperListResponseVariants; - -[JsonConverter(typeof(VariantConverter))] -public sealed record class CompletedSmartscraperVariant(CompletedSmartscraper Value) - : SmartscraperListResponse, - IVariant -{ - public static CompletedSmartscraperVariant From(CompletedSmartscraper value) - { - return new(value); - } - - public override void Validate() - { - this.Value.Validate(); - } -} - -[JsonConverter(typeof(VariantConverter))] -public sealed record class FailedSmartscraperVariant(FailedSmartscraper Value) - : SmartscraperListResponse, - IVariant -{ - public static FailedSmartscraperVariant From(FailedSmartscraper value) - { - return new(value); - } - - public override void Validate() - { - this.Value.Validate(); - } -} diff --git a/src/Scrapegraphai/Models/Smartscraper/SmartscraperRetrieveParams.cs b/src/Scrapegraphai/Models/Smartscraper/SmartscraperRetrieveParams.cs index 68dcbce..9e3f89e 100644 --- a/src/Scrapegraphai/Models/Smartscraper/SmartscraperRetrieveParams.cs +++ b/src/Scrapegraphai/Models/Smartscraper/SmartscraperRetrieveParams.cs @@ -1,5 +1,6 @@ using System; using System.Net.Http; +using Scrapegraphai.Core; namespace Scrapegraphai.Models.Smartscraper; @@ -21,7 +22,10 @@ public override Uri Url(IScrapegraphaiClient client) }.Uri; } - public void AddHeadersToRequest(HttpRequestMessage request, IScrapegraphaiClient client) + internal override void AddHeadersToRequest( + HttpRequestMessage request, + IScrapegraphaiClient client + ) { ParamsBase.AddDefaultHeaders(request, client); foreach (var item in this.HeaderProperties) diff --git a/src/Scrapegraphai/Models/Smartscraper/SmartscraperRetrieveResponse.cs b/src/Scrapegraphai/Models/Smartscraper/SmartscraperRetrieveResponse.cs index a40547b..4c73cd0 100644 --- a/src/Scrapegraphai/Models/Smartscraper/SmartscraperRetrieveResponse.cs +++ b/src/Scrapegraphai/Models/Smartscraper/SmartscraperRetrieveResponse.cs @@ -1,18 +1,213 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; using System.Text.Json.Serialization; -using SmartscraperRetrieveResponseVariants = Scrapegraphai.Models.Smartscraper.SmartscraperRetrieveResponseVariants; +using Scrapegraphai.Exceptions; namespace Scrapegraphai.Models.Smartscraper; -[JsonConverter(typeof(UnionConverter))] -public abstract record class SmartscraperRetrieveResponse +[JsonConverter(typeof(SmartscraperRetrieveResponseConverter))] +public record class SmartscraperRetrieveResponse { - internal SmartscraperRetrieveResponse() { } + public object Value { get; private init; } - public static implicit operator SmartscraperRetrieveResponse(CompletedSmartscraper value) => - new SmartscraperRetrieveResponseVariants::CompletedSmartscraperVariant(value); + public string? Error + { + get + { + return Match( + completedSmartscraper: (x) => x.Error, + failedSmartscraper: (x) => x.Error + ); + } + } - public static implicit operator SmartscraperRetrieveResponse(FailedSmartscraper value) => - new SmartscraperRetrieveResponseVariants::FailedSmartscraperVariant(value); + public string? RequestID + { + get + { + return Match( + completedSmartscraper: (x) => x.RequestID, + failedSmartscraper: (x) => x.RequestID + ); + } + } - public abstract void Validate(); + public JsonElement? Result + { + get + { + return Match( + completedSmartscraper: (x) => x.Result, + failedSmartscraper: (x) => x.Result + ); + } + } + + public string? UserPrompt + { + get + { + return Match( + completedSmartscraper: (x) => x.UserPrompt, + failedSmartscraper: (x) => x.UserPrompt + ); + } + } + + public string? WebsiteURL + { + get + { + return Match( + completedSmartscraper: (x) => x.WebsiteURL, + failedSmartscraper: (x) => x.WebsiteURL + ); + } + } + + public SmartscraperRetrieveResponse(CompletedSmartscraper value) + { + Value = value; + } + + public SmartscraperRetrieveResponse(FailedSmartscraper value) + { + Value = value; + } + + SmartscraperRetrieveResponse(UnknownVariant value) + { + Value = value; + } + + public static SmartscraperRetrieveResponse CreateUnknownVariant(JsonElement value) + { + return new(new UnknownVariant(value)); + } + + public bool TryPickCompletedSmartscraper([NotNullWhen(true)] out CompletedSmartscraper? value) + { + value = this.Value as CompletedSmartscraper; + return value != null; + } + + public bool TryPickFailedSmartscraper([NotNullWhen(true)] out FailedSmartscraper? value) + { + value = this.Value as FailedSmartscraper; + return value != null; + } + + public void Switch( + Action completedSmartscraper, + Action failedSmartscraper + ) + { + switch (this.Value) + { + case CompletedSmartscraper value: + completedSmartscraper(value); + break; + case FailedSmartscraper value: + failedSmartscraper(value); + break; + default: + throw new ScrapegraphaiInvalidDataException( + "Data did not match any variant of SmartscraperRetrieveResponse" + ); + } + } + + public T Match( + Func completedSmartscraper, + Func failedSmartscraper + ) + { + return this.Value switch + { + CompletedSmartscraper value => completedSmartscraper(value), + FailedSmartscraper value => failedSmartscraper(value), + _ => throw new ScrapegraphaiInvalidDataException( + "Data did not match any variant of SmartscraperRetrieveResponse" + ), + }; + } + + public void Validate() + { + if (this.Value is not UnknownVariant) + { + throw new ScrapegraphaiInvalidDataException( + "Data did not match any variant of SmartscraperRetrieveResponse" + ); + } + } + + private record struct UnknownVariant(JsonElement value); +} + +sealed class SmartscraperRetrieveResponseConverter : JsonConverter +{ + public override SmartscraperRetrieveResponse? Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options + ) + { + List exceptions = []; + + try + { + var deserialized = JsonSerializer.Deserialize( + ref reader, + options + ); + if (deserialized != null) + { + deserialized.Validate(); + return new SmartscraperRetrieveResponse(deserialized); + } + } + catch (Exception e) when (e is JsonException || e is ScrapegraphaiInvalidDataException) + { + exceptions.Add( + new ScrapegraphaiInvalidDataException( + "Data does not match union variant 'CompletedSmartscraper'", + e + ) + ); + } + + try + { + var deserialized = JsonSerializer.Deserialize(ref reader, options); + if (deserialized != null) + { + deserialized.Validate(); + return new SmartscraperRetrieveResponse(deserialized); + } + } + catch (Exception e) when (e is JsonException || e is ScrapegraphaiInvalidDataException) + { + exceptions.Add( + new ScrapegraphaiInvalidDataException( + "Data does not match union variant 'FailedSmartscraper'", + e + ) + ); + } + + throw new AggregateException(exceptions); + } + + public override void Write( + Utf8JsonWriter writer, + SmartscraperRetrieveResponse value, + JsonSerializerOptions options + ) + { + object variant = value.Value; + JsonSerializer.Serialize(writer, variant, options); + } } diff --git a/src/Scrapegraphai/Models/Smartscraper/SmartscraperRetrieveResponseVariants/All.cs b/src/Scrapegraphai/Models/Smartscraper/SmartscraperRetrieveResponseVariants/All.cs deleted file mode 100644 index b85460c..0000000 --- a/src/Scrapegraphai/Models/Smartscraper/SmartscraperRetrieveResponseVariants/All.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Text.Json.Serialization; - -namespace Scrapegraphai.Models.Smartscraper.SmartscraperRetrieveResponseVariants; - -[JsonConverter(typeof(VariantConverter))] -public sealed record class CompletedSmartscraperVariant(CompletedSmartscraper Value) - : SmartscraperRetrieveResponse, - IVariant -{ - public static CompletedSmartscraperVariant From(CompletedSmartscraper value) - { - return new(value); - } - - public override void Validate() - { - this.Value.Validate(); - } -} - -[JsonConverter(typeof(VariantConverter))] -public sealed record class FailedSmartscraperVariant(FailedSmartscraper Value) - : SmartscraperRetrieveResponse, - IVariant -{ - public static FailedSmartscraperVariant From(FailedSmartscraper value) - { - return new(value); - } - - public override void Validate() - { - this.Value.Validate(); - } -} diff --git a/src/Scrapegraphai/Models/Validate/ValidateAPIKeyParams.cs b/src/Scrapegraphai/Models/Validate/ValidateAPIKeyParams.cs index bd8cc21..a3ce9eb 100644 --- a/src/Scrapegraphai/Models/Validate/ValidateAPIKeyParams.cs +++ b/src/Scrapegraphai/Models/Validate/ValidateAPIKeyParams.cs @@ -1,5 +1,6 @@ using System; using System.Net.Http; +using Scrapegraphai.Core; namespace Scrapegraphai.Models.Validate; @@ -16,7 +17,10 @@ public override Uri Url(IScrapegraphaiClient client) }.Uri; } - public void AddHeadersToRequest(HttpRequestMessage request, IScrapegraphaiClient client) + internal override void AddHeadersToRequest( + HttpRequestMessage request, + IScrapegraphaiClient client + ) { ParamsBase.AddDefaultHeaders(request, client); foreach (var item in this.HeaderProperties) diff --git a/src/Scrapegraphai/Models/Validate/ValidateAPIKeyResponse.cs b/src/Scrapegraphai/Models/Validate/ValidateAPIKeyResponse.cs index 743d108..4d5e286 100644 --- a/src/Scrapegraphai/Models/Validate/ValidateAPIKeyResponse.cs +++ b/src/Scrapegraphai/Models/Validate/ValidateAPIKeyResponse.cs @@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; +using Scrapegraphai.Core; namespace Scrapegraphai.Models.Validate; @@ -17,7 +18,13 @@ public string? Email return JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); } - set { this.Properties["email"] = JsonSerializer.SerializeToElement(value); } + set + { + this.Properties["email"] = JsonSerializer.SerializeToElement( + value, + ModelBase.SerializerOptions + ); + } } public override void Validate() diff --git a/src/Scrapegraphai/Null.cs b/src/Scrapegraphai/Null.cs deleted file mode 100644 index 925b4e2..0000000 --- a/src/Scrapegraphai/Null.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Scrapegraphai; - -public sealed record class Null -{ - Null() { } -} diff --git a/src/Scrapegraphai/Scrapegraphai.csproj b/src/Scrapegraphai/Scrapegraphai.csproj index ab444f7..53162f0 100644 --- a/src/Scrapegraphai/Scrapegraphai.csproj +++ b/src/Scrapegraphai/Scrapegraphai.csproj @@ -6,33 +6,30 @@ SDK Code Generation Scrapegraphai C# Apache-2.0 enable - 0.0.1 + 0.1.0 net8.0 latest true README.md - https://www.github.com/stainless-sdks/scrapegraphai-csharp + https://www.github.com/ScrapeGraphAI/scrapegraphai-c git true true $(NoWarn),1570,1573,1574,1591 - + $(NoWarn),IL2026,IL3050 Debug;Release - true - true + true + true disable - + + + + diff --git a/src/Scrapegraphai/ScrapegraphaiClient.cs b/src/Scrapegraphai/ScrapegraphaiClient.cs index 33d5942..e76c681 100644 --- a/src/Scrapegraphai/ScrapegraphaiClient.cs +++ b/src/Scrapegraphai/ScrapegraphaiClient.cs @@ -1,36 +1,42 @@ -using Crawl = Scrapegraphai.Services.Crawl; -using Credits = Scrapegraphai.Services.Credits; -using Feedback = Scrapegraphai.Services.Feedback; -using GenerateSchema = Scrapegraphai.Services.GenerateSchema; -using Healthz = Scrapegraphai.Services.Healthz; -using Http = System.Net.Http; -using Markdownify = Scrapegraphai.Services.Markdownify; -using Searchscraper = Scrapegraphai.Services.Searchscraper; -using Smartscraper = Scrapegraphai.Services.Smartscraper; -using System = System; -using Validate = Scrapegraphai.Services.Validate; +using System; +using System.Net.Http; +using System.Threading.Tasks; +using Scrapegraphai.Core; +using Scrapegraphai.Exceptions; +using Scrapegraphai.Services.Crawl; +using Scrapegraphai.Services.Credits; +using Scrapegraphai.Services.Feedback; +using Scrapegraphai.Services.GenerateSchema; +using Scrapegraphai.Services.Healthz; +using Scrapegraphai.Services.Markdownify; +using Scrapegraphai.Services.Searchscraper; +using Scrapegraphai.Services.Smartscraper; +using Scrapegraphai.Services.Validate; namespace Scrapegraphai; public sealed class ScrapegraphaiClient : IScrapegraphaiClient { - public Http::HttpClient HttpClient { get; init; } = new(); + public HttpClient HttpClient { get; init; } = new(); - System::Lazy _baseUrl = new(() => - new System::Uri( - System::Environment.GetEnvironmentVariable("SCRAPEGRAPHAI_BASE_URL") + Lazy _baseUrl = new(() => + new Uri( + Environment.GetEnvironmentVariable("SCRAPEGRAPHAI_BASE_URL") ?? "https://api.scrapegraphai.com/v1" ) ); - public System::Uri BaseUrl + public Uri BaseUrl { get { return _baseUrl.Value; } init { _baseUrl = new(() => value); } } - System::Lazy _apiKey = new(() => - System::Environment.GetEnvironmentVariable("SCRAPEGRAPHAI_API_KEY") - ?? throw new System::ArgumentNullException(nameof(APIKey)) + Lazy _apiKey = new(() => + Environment.GetEnvironmentVariable("SCRAPEGRAPHAI_API_KEY") + ?? throw new ScrapegraphaiInvalidDataException( + string.Format("{0} cannot be null", nameof(APIKey)), + new ArgumentNullException(nameof(APIKey)) + ) ); public string APIKey { @@ -38,70 +44,110 @@ public string APIKey init { _apiKey = new(() => value); } } - readonly System::Lazy _smartscraper; - public Smartscraper::ISmartscraperService Smartscraper + readonly Lazy _smartscraper; + public ISmartscraperService Smartscraper { get { return _smartscraper.Value; } } - readonly System::Lazy _markdownify; - public Markdownify::IMarkdownifyService Markdownify + readonly Lazy _markdownify; + public IMarkdownifyService Markdownify { get { return _markdownify.Value; } } - readonly System::Lazy _searchscraper; - public Searchscraper::ISearchscraperService Searchscraper + readonly Lazy _searchscraper; + public ISearchscraperService Searchscraper { get { return _searchscraper.Value; } } - readonly System::Lazy _generateSchema; - public GenerateSchema::IGenerateSchemaService GenerateSchema + readonly Lazy _generateSchema; + public IGenerateSchemaService GenerateSchema { get { return _generateSchema.Value; } } - readonly System::Lazy _crawl; - public Crawl::ICrawlService Crawl + readonly Lazy _crawl; + public ICrawlService Crawl { get { return _crawl.Value; } } - readonly System::Lazy _credits; - public Credits::ICreditService Credits + readonly Lazy _credits; + public ICreditService Credits { get { return _credits.Value; } } - readonly System::Lazy _validate; - public Validate::IValidateService Validate + readonly Lazy _validate; + public IValidateService Validate { get { return _validate.Value; } } - readonly System::Lazy _feedback; - public Feedback::IFeedbackService Feedback + readonly Lazy _feedback; + public IFeedbackService Feedback { get { return _feedback.Value; } } - readonly System::Lazy _healthz; - public Healthz::IHealthzService Healthz + readonly Lazy _healthz; + public IHealthzService Healthz { get { return _healthz.Value; } } + public async Task Execute(HttpRequest request) + where T : ParamsBase + { + using HttpRequestMessage requestMessage = new(request.Method, request.Params.Url(this)) + { + Content = request.Params.BodyContent(), + }; + request.Params.AddHeadersToRequest(requestMessage, this); + HttpResponseMessage responseMessage; + try + { + responseMessage = await this + .HttpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead) + .ConfigureAwait(false); + } + catch (HttpRequestException e1) + { + throw new ScrapegraphaiIOException("I/O exception", e1); + } + if (!responseMessage.IsSuccessStatusCode) + { + try + { + throw ScrapegraphaiExceptionFactory.CreateApiException( + responseMessage.StatusCode, + await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false) + ); + } + catch (HttpRequestException e) + { + throw new ScrapegraphaiIOException("I/O Exception", e); + } + finally + { + responseMessage.Dispose(); + } + } + return new() { Message = responseMessage }; + } + public ScrapegraphaiClient() { - _smartscraper = new(() => new Smartscraper::SmartscraperService(this)); - _markdownify = new(() => new Markdownify::MarkdownifyService(this)); - _searchscraper = new(() => new Searchscraper::SearchscraperService(this)); - _generateSchema = new(() => new GenerateSchema::GenerateSchemaService(this)); - _crawl = new(() => new Crawl::CrawlService(this)); - _credits = new(() => new Credits::CreditService(this)); - _validate = new(() => new Validate::ValidateService(this)); - _feedback = new(() => new Feedback::FeedbackService(this)); - _healthz = new(() => new Healthz::HealthzService(this)); + _smartscraper = new(() => new SmartscraperService(this)); + _markdownify = new(() => new MarkdownifyService(this)); + _searchscraper = new(() => new SearchscraperService(this)); + _generateSchema = new(() => new GenerateSchemaService(this)); + _crawl = new(() => new CrawlService(this)); + _credits = new(() => new CreditService(this)); + _validate = new(() => new ValidateService(this)); + _feedback = new(() => new FeedbackService(this)); + _healthz = new(() => new HealthzService(this)); } } diff --git a/src/Scrapegraphai/Services/Crawl/CrawlService.cs b/src/Scrapegraphai/Services/Crawl/CrawlService.cs index b15fba1..947c729 100644 --- a/src/Scrapegraphai/Services/Crawl/CrawlService.cs +++ b/src/Scrapegraphai/Services/Crawl/CrawlService.cs @@ -1,7 +1,6 @@ -using System; using System.Net.Http; -using System.Text.Json; using System.Threading.Tasks; +using Scrapegraphai.Core; using Scrapegraphai.Models.Crawl; namespace Scrapegraphai.Services.Crawl; @@ -19,46 +18,23 @@ public async Task RetrieveResults( CrawlRetrieveResultsParams parameters ) { - using HttpRequestMessage request = new(HttpMethod.Get, parameters.Url(this._client)); - parameters.AddHeadersToRequest(request, this._client); - using HttpResponseMessage response = await this - ._client.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) - .ConfigureAwait(false); - if (!response.IsSuccessStatusCode) + HttpRequest request = new() { - throw new HttpException( - response.StatusCode, - await response.Content.ReadAsStringAsync().ConfigureAwait(false) - ); - } - - return JsonSerializer.Deserialize( - await response.Content.ReadAsStreamAsync().ConfigureAwait(false), - ModelBase.SerializerOptions - ) ?? throw new NullReferenceException(); + Method = HttpMethod.Get, + Params = parameters, + }; + using var response = await this._client.Execute(request).ConfigureAwait(false); + return await response.Deserialize().ConfigureAwait(false); } public async Task Start(CrawlStartParams parameters) { - using HttpRequestMessage request = new(HttpMethod.Post, parameters.Url(this._client)) + HttpRequest request = new() { - Content = parameters.BodyContent(), + Method = HttpMethod.Post, + Params = parameters, }; - parameters.AddHeadersToRequest(request, this._client); - using HttpResponseMessage response = await this - ._client.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) - .ConfigureAwait(false); - if (!response.IsSuccessStatusCode) - { - throw new HttpException( - response.StatusCode, - await response.Content.ReadAsStringAsync().ConfigureAwait(false) - ); - } - - return JsonSerializer.Deserialize( - await response.Content.ReadAsStreamAsync().ConfigureAwait(false), - ModelBase.SerializerOptions - ) ?? throw new NullReferenceException(); + using var response = await this._client.Execute(request).ConfigureAwait(false); + return await response.Deserialize().ConfigureAwait(false); } } diff --git a/src/Scrapegraphai/Services/Credits/CreditService.cs b/src/Scrapegraphai/Services/Credits/CreditService.cs index 5eb6b4e..88f1c8b 100644 --- a/src/Scrapegraphai/Services/Credits/CreditService.cs +++ b/src/Scrapegraphai/Services/Credits/CreditService.cs @@ -1,7 +1,6 @@ -using System; using System.Net.Http; -using System.Text.Json; using System.Threading.Tasks; +using Scrapegraphai.Core; using Scrapegraphai.Models.Credits; namespace Scrapegraphai.Services.Credits; @@ -15,24 +14,16 @@ public CreditService(IScrapegraphaiClient client) _client = client; } - public async Task Retrieve(CreditRetrieveParams parameters) + public async Task Retrieve(CreditRetrieveParams? parameters = null) { - using HttpRequestMessage request = new(HttpMethod.Get, parameters.Url(this._client)); - parameters.AddHeadersToRequest(request, this._client); - using HttpResponseMessage response = await this - ._client.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) - .ConfigureAwait(false); - if (!response.IsSuccessStatusCode) - { - throw new HttpException( - response.StatusCode, - await response.Content.ReadAsStringAsync().ConfigureAwait(false) - ); - } + parameters ??= new(); - return JsonSerializer.Deserialize( - await response.Content.ReadAsStreamAsync().ConfigureAwait(false), - ModelBase.SerializerOptions - ) ?? throw new NullReferenceException(); + HttpRequest request = new() + { + Method = HttpMethod.Get, + Params = parameters, + }; + using var response = await this._client.Execute(request).ConfigureAwait(false); + return await response.Deserialize().ConfigureAwait(false); } } diff --git a/src/Scrapegraphai/Services/Credits/ICreditService.cs b/src/Scrapegraphai/Services/Credits/ICreditService.cs index c251b59..ad3c09d 100644 --- a/src/Scrapegraphai/Services/Credits/ICreditService.cs +++ b/src/Scrapegraphai/Services/Credits/ICreditService.cs @@ -8,5 +8,5 @@ public interface ICreditService /// /// Retrieve the current credit balance and usage for the authenticated user /// - Task Retrieve(CreditRetrieveParams parameters); + Task Retrieve(CreditRetrieveParams? parameters = null); } diff --git a/src/Scrapegraphai/Services/Feedback/FeedbackService.cs b/src/Scrapegraphai/Services/Feedback/FeedbackService.cs index ab17e9a..efc1838 100644 --- a/src/Scrapegraphai/Services/Feedback/FeedbackService.cs +++ b/src/Scrapegraphai/Services/Feedback/FeedbackService.cs @@ -1,7 +1,6 @@ -using System; using System.Net.Http; -using System.Text.Json; using System.Threading.Tasks; +using Scrapegraphai.Core; using Scrapegraphai.Models.Feedback; namespace Scrapegraphai.Services.Feedback; @@ -17,25 +16,12 @@ public FeedbackService(IScrapegraphaiClient client) public async Task Submit(FeedbackSubmitParams parameters) { - using HttpRequestMessage request = new(HttpMethod.Post, parameters.Url(this._client)) + HttpRequest request = new() { - Content = parameters.BodyContent(), + Method = HttpMethod.Post, + Params = parameters, }; - parameters.AddHeadersToRequest(request, this._client); - using HttpResponseMessage response = await this - ._client.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) - .ConfigureAwait(false); - if (!response.IsSuccessStatusCode) - { - throw new HttpException( - response.StatusCode, - await response.Content.ReadAsStringAsync().ConfigureAwait(false) - ); - } - - return JsonSerializer.Deserialize( - await response.Content.ReadAsStreamAsync().ConfigureAwait(false), - ModelBase.SerializerOptions - ) ?? throw new NullReferenceException(); + using var response = await this._client.Execute(request).ConfigureAwait(false); + return await response.Deserialize().ConfigureAwait(false); } } diff --git a/src/Scrapegraphai/Services/GenerateSchema/GenerateSchemaService.cs b/src/Scrapegraphai/Services/GenerateSchema/GenerateSchemaService.cs index db4a5e8..4b41eb2 100644 --- a/src/Scrapegraphai/Services/GenerateSchema/GenerateSchemaService.cs +++ b/src/Scrapegraphai/Services/GenerateSchema/GenerateSchemaService.cs @@ -1,7 +1,6 @@ -using System; using System.Net.Http; -using System.Text.Json; using System.Threading.Tasks; +using Scrapegraphai.Core; using Scrapegraphai.Models.GenerateSchema; namespace Scrapegraphai.Services.GenerateSchema; @@ -17,48 +16,25 @@ public GenerateSchemaService(IScrapegraphaiClient client) public async Task Create(GenerateSchemaCreateParams parameters) { - using HttpRequestMessage request = new(HttpMethod.Post, parameters.Url(this._client)) + HttpRequest request = new() { - Content = parameters.BodyContent(), + Method = HttpMethod.Post, + Params = parameters, }; - parameters.AddHeadersToRequest(request, this._client); - using HttpResponseMessage response = await this - ._client.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) - .ConfigureAwait(false); - if (!response.IsSuccessStatusCode) - { - throw new HttpException( - response.StatusCode, - await response.Content.ReadAsStringAsync().ConfigureAwait(false) - ); - } - - return JsonSerializer.Deserialize( - await response.Content.ReadAsStreamAsync().ConfigureAwait(false), - ModelBase.SerializerOptions - ) ?? throw new NullReferenceException(); + using var response = await this._client.Execute(request).ConfigureAwait(false); + return await response.Deserialize().ConfigureAwait(false); } public async Task Retrieve( GenerateSchemaRetrieveParams parameters ) { - using HttpRequestMessage request = new(HttpMethod.Get, parameters.Url(this._client)); - parameters.AddHeadersToRequest(request, this._client); - using HttpResponseMessage response = await this - ._client.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) - .ConfigureAwait(false); - if (!response.IsSuccessStatusCode) + HttpRequest request = new() { - throw new HttpException( - response.StatusCode, - await response.Content.ReadAsStringAsync().ConfigureAwait(false) - ); - } - - return JsonSerializer.Deserialize( - await response.Content.ReadAsStreamAsync().ConfigureAwait(false), - ModelBase.SerializerOptions - ) ?? throw new NullReferenceException(); + Method = HttpMethod.Get, + Params = parameters, + }; + using var response = await this._client.Execute(request).ConfigureAwait(false); + return await response.Deserialize().ConfigureAwait(false); } } diff --git a/src/Scrapegraphai/Services/Healthz/HealthzService.cs b/src/Scrapegraphai/Services/Healthz/HealthzService.cs index 38caeb3..f884f83 100644 --- a/src/Scrapegraphai/Services/Healthz/HealthzService.cs +++ b/src/Scrapegraphai/Services/Healthz/HealthzService.cs @@ -1,7 +1,6 @@ -using System; using System.Net.Http; -using System.Text.Json; using System.Threading.Tasks; +using Scrapegraphai.Core; using Scrapegraphai.Models.Healthz; namespace Scrapegraphai.Services.Healthz; @@ -15,24 +14,16 @@ public HealthzService(IScrapegraphaiClient client) _client = client; } - public async Task Check(HealthzCheckParams parameters) + public async Task Check(HealthzCheckParams? parameters = null) { - using HttpRequestMessage request = new(HttpMethod.Get, parameters.Url(this._client)); - parameters.AddHeadersToRequest(request, this._client); - using HttpResponseMessage response = await this - ._client.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) - .ConfigureAwait(false); - if (!response.IsSuccessStatusCode) - { - throw new HttpException( - response.StatusCode, - await response.Content.ReadAsStringAsync().ConfigureAwait(false) - ); - } + parameters ??= new(); - return JsonSerializer.Deserialize( - await response.Content.ReadAsStreamAsync().ConfigureAwait(false), - ModelBase.SerializerOptions - ) ?? throw new NullReferenceException(); + HttpRequest request = new() + { + Method = HttpMethod.Get, + Params = parameters, + }; + using var response = await this._client.Execute(request).ConfigureAwait(false); + return await response.Deserialize().ConfigureAwait(false); } } diff --git a/src/Scrapegraphai/Services/Healthz/IHealthzService.cs b/src/Scrapegraphai/Services/Healthz/IHealthzService.cs index a6d84cd..e6ea316 100644 --- a/src/Scrapegraphai/Services/Healthz/IHealthzService.cs +++ b/src/Scrapegraphai/Services/Healthz/IHealthzService.cs @@ -8,5 +8,5 @@ public interface IHealthzService /// /// Check the health status of the service /// - Task Check(HealthzCheckParams parameters); + Task Check(HealthzCheckParams? parameters = null); } diff --git a/src/Scrapegraphai/Services/Markdownify/MarkdownifyService.cs b/src/Scrapegraphai/Services/Markdownify/MarkdownifyService.cs index b102e9a..94b37da 100644 --- a/src/Scrapegraphai/Services/Markdownify/MarkdownifyService.cs +++ b/src/Scrapegraphai/Services/Markdownify/MarkdownifyService.cs @@ -1,7 +1,6 @@ -using System; using System.Net.Http; -using System.Text.Json; using System.Threading.Tasks; +using Scrapegraphai.Core; using Scrapegraphai.Models.Markdownify; namespace Scrapegraphai.Services.Markdownify; @@ -17,48 +16,27 @@ public MarkdownifyService(IScrapegraphaiClient client) public async Task Convert(MarkdownifyConvertParams parameters) { - using HttpRequestMessage request = new(HttpMethod.Post, parameters.Url(this._client)) + HttpRequest request = new() { - Content = parameters.BodyContent(), + Method = HttpMethod.Post, + Params = parameters, }; - parameters.AddHeadersToRequest(request, this._client); - using HttpResponseMessage response = await this - ._client.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) - .ConfigureAwait(false); - if (!response.IsSuccessStatusCode) - { - throw new HttpException( - response.StatusCode, - await response.Content.ReadAsStringAsync().ConfigureAwait(false) - ); - } - - return JsonSerializer.Deserialize( - await response.Content.ReadAsStreamAsync().ConfigureAwait(false), - ModelBase.SerializerOptions - ) ?? throw new NullReferenceException(); + using var response = await this._client.Execute(request).ConfigureAwait(false); + return await response.Deserialize().ConfigureAwait(false); } public async Task RetrieveStatus( MarkdownifyRetrieveStatusParams parameters ) { - using HttpRequestMessage request = new(HttpMethod.Get, parameters.Url(this._client)); - parameters.AddHeadersToRequest(request, this._client); - using HttpResponseMessage response = await this - ._client.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) - .ConfigureAwait(false); - if (!response.IsSuccessStatusCode) + HttpRequest request = new() { - throw new HttpException( - response.StatusCode, - await response.Content.ReadAsStringAsync().ConfigureAwait(false) - ); - } - - return JsonSerializer.Deserialize( - await response.Content.ReadAsStreamAsync().ConfigureAwait(false), - ModelBase.SerializerOptions - ) ?? throw new NullReferenceException(); + Method = HttpMethod.Get, + Params = parameters, + }; + using var response = await this._client.Execute(request).ConfigureAwait(false); + return await response + .Deserialize() + .ConfigureAwait(false); } } diff --git a/src/Scrapegraphai/Services/Searchscraper/SearchscraperService.cs b/src/Scrapegraphai/Services/Searchscraper/SearchscraperService.cs index e033ae3..2ef1448 100644 --- a/src/Scrapegraphai/Services/Searchscraper/SearchscraperService.cs +++ b/src/Scrapegraphai/Services/Searchscraper/SearchscraperService.cs @@ -1,7 +1,6 @@ -using System; using System.Net.Http; -using System.Text.Json; using System.Threading.Tasks; +using Scrapegraphai.Core; using Scrapegraphai.Models.Searchscraper; namespace Scrapegraphai.Services.Searchscraper; @@ -17,48 +16,27 @@ public SearchscraperService(IScrapegraphaiClient client) public async Task Create(SearchscraperCreateParams parameters) { - using HttpRequestMessage request = new(HttpMethod.Post, parameters.Url(this._client)) + HttpRequest request = new() { - Content = parameters.BodyContent(), + Method = HttpMethod.Post, + Params = parameters, }; - parameters.AddHeadersToRequest(request, this._client); - using HttpResponseMessage response = await this - ._client.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) - .ConfigureAwait(false); - if (!response.IsSuccessStatusCode) - { - throw new HttpException( - response.StatusCode, - await response.Content.ReadAsStringAsync().ConfigureAwait(false) - ); - } - - return JsonSerializer.Deserialize( - await response.Content.ReadAsStreamAsync().ConfigureAwait(false), - ModelBase.SerializerOptions - ) ?? throw new NullReferenceException(); + using var response = await this._client.Execute(request).ConfigureAwait(false); + return await response.Deserialize().ConfigureAwait(false); } public async Task RetrieveStatus( SearchscraperRetrieveStatusParams parameters ) { - using HttpRequestMessage request = new(HttpMethod.Get, parameters.Url(this._client)); - parameters.AddHeadersToRequest(request, this._client); - using HttpResponseMessage response = await this - ._client.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) - .ConfigureAwait(false); - if (!response.IsSuccessStatusCode) + HttpRequest request = new() { - throw new HttpException( - response.StatusCode, - await response.Content.ReadAsStringAsync().ConfigureAwait(false) - ); - } - - return JsonSerializer.Deserialize( - await response.Content.ReadAsStreamAsync().ConfigureAwait(false), - ModelBase.SerializerOptions - ) ?? throw new NullReferenceException(); + Method = HttpMethod.Get, + Params = parameters, + }; + using var response = await this._client.Execute(request).ConfigureAwait(false); + return await response + .Deserialize() + .ConfigureAwait(false); } } diff --git a/src/Scrapegraphai/Services/Smartscraper/ISmartscraperService.cs b/src/Scrapegraphai/Services/Smartscraper/ISmartscraperService.cs index 3249a9b..ef2fde4 100644 --- a/src/Scrapegraphai/Services/Smartscraper/ISmartscraperService.cs +++ b/src/Scrapegraphai/Services/Smartscraper/ISmartscraperService.cs @@ -19,5 +19,5 @@ public interface ISmartscraperService /// /// Retrieve the status and results of a scraping operation /// - Task List(SmartscraperListParams parameters); + Task List(SmartscraperListParams? parameters = null); } diff --git a/src/Scrapegraphai/Services/Smartscraper/SmartscraperService.cs b/src/Scrapegraphai/Services/Smartscraper/SmartscraperService.cs index 129d753..bebaeac 100644 --- a/src/Scrapegraphai/Services/Smartscraper/SmartscraperService.cs +++ b/src/Scrapegraphai/Services/Smartscraper/SmartscraperService.cs @@ -1,7 +1,6 @@ -using System; using System.Net.Http; -using System.Text.Json; using System.Threading.Tasks; +using Scrapegraphai.Core; using Scrapegraphai.Models.Smartscraper; namespace Scrapegraphai.Services.Smartscraper; @@ -17,67 +16,36 @@ public SmartscraperService(IScrapegraphaiClient client) public async Task Create(SmartscraperCreateParams parameters) { - using HttpRequestMessage request = new(HttpMethod.Post, parameters.Url(this._client)) + HttpRequest request = new() { - Content = parameters.BodyContent(), + Method = HttpMethod.Post, + Params = parameters, }; - parameters.AddHeadersToRequest(request, this._client); - using HttpResponseMessage response = await this - ._client.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) - .ConfigureAwait(false); - if (!response.IsSuccessStatusCode) - { - throw new HttpException( - response.StatusCode, - await response.Content.ReadAsStringAsync().ConfigureAwait(false) - ); - } - - return JsonSerializer.Deserialize( - await response.Content.ReadAsStreamAsync().ConfigureAwait(false), - ModelBase.SerializerOptions - ) ?? throw new NullReferenceException(); + using var response = await this._client.Execute(request).ConfigureAwait(false); + return await response.Deserialize().ConfigureAwait(false); } public async Task Retrieve(SmartscraperRetrieveParams parameters) { - using HttpRequestMessage request = new(HttpMethod.Get, parameters.Url(this._client)); - parameters.AddHeadersToRequest(request, this._client); - using HttpResponseMessage response = await this - ._client.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) - .ConfigureAwait(false); - if (!response.IsSuccessStatusCode) + HttpRequest request = new() { - throw new HttpException( - response.StatusCode, - await response.Content.ReadAsStringAsync().ConfigureAwait(false) - ); - } - - return JsonSerializer.Deserialize( - await response.Content.ReadAsStreamAsync().ConfigureAwait(false), - ModelBase.SerializerOptions - ) ?? throw new NullReferenceException(); + Method = HttpMethod.Get, + Params = parameters, + }; + using var response = await this._client.Execute(request).ConfigureAwait(false); + return await response.Deserialize().ConfigureAwait(false); } - public async Task List(SmartscraperListParams parameters) + public async Task List(SmartscraperListParams? parameters = null) { - using HttpRequestMessage request = new(HttpMethod.Get, parameters.Url(this._client)); - parameters.AddHeadersToRequest(request, this._client); - using HttpResponseMessage response = await this - ._client.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) - .ConfigureAwait(false); - if (!response.IsSuccessStatusCode) - { - throw new HttpException( - response.StatusCode, - await response.Content.ReadAsStringAsync().ConfigureAwait(false) - ); - } + parameters ??= new(); - return JsonSerializer.Deserialize( - await response.Content.ReadAsStreamAsync().ConfigureAwait(false), - ModelBase.SerializerOptions - ) ?? throw new NullReferenceException(); + HttpRequest request = new() + { + Method = HttpMethod.Get, + Params = parameters, + }; + using var response = await this._client.Execute(request).ConfigureAwait(false); + return await response.Deserialize().ConfigureAwait(false); } } diff --git a/src/Scrapegraphai/Services/Validate/IValidateService.cs b/src/Scrapegraphai/Services/Validate/IValidateService.cs index f91bd1c..ecfeaf4 100644 --- a/src/Scrapegraphai/Services/Validate/IValidateService.cs +++ b/src/Scrapegraphai/Services/Validate/IValidateService.cs @@ -8,5 +8,5 @@ public interface IValidateService /// /// Validate the API key and retrieve associated user email /// - Task APIKey(ValidateAPIKeyParams parameters); + Task APIKey(ValidateAPIKeyParams? parameters = null); } diff --git a/src/Scrapegraphai/Services/Validate/ValidateService.cs b/src/Scrapegraphai/Services/Validate/ValidateService.cs index 1f5aeb0..30e8222 100644 --- a/src/Scrapegraphai/Services/Validate/ValidateService.cs +++ b/src/Scrapegraphai/Services/Validate/ValidateService.cs @@ -1,7 +1,6 @@ -using System; using System.Net.Http; -using System.Text.Json; using System.Threading.Tasks; +using Scrapegraphai.Core; using Scrapegraphai.Models.Validate; namespace Scrapegraphai.Services.Validate; @@ -15,24 +14,16 @@ public ValidateService(IScrapegraphaiClient client) _client = client; } - public async Task APIKey(ValidateAPIKeyParams parameters) + public async Task APIKey(ValidateAPIKeyParams? parameters = null) { - using HttpRequestMessage request = new(HttpMethod.Get, parameters.Url(this._client)); - parameters.AddHeadersToRequest(request, this._client); - using HttpResponseMessage response = await this - ._client.HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead) - .ConfigureAwait(false); - if (!response.IsSuccessStatusCode) - { - throw new HttpException( - response.StatusCode, - await response.Content.ReadAsStringAsync().ConfigureAwait(false) - ); - } + parameters ??= new(); - return JsonSerializer.Deserialize( - await response.Content.ReadAsStreamAsync().ConfigureAwait(false), - ModelBase.SerializerOptions - ) ?? throw new NullReferenceException(); + HttpRequest request = new() + { + Method = HttpMethod.Get, + Params = parameters, + }; + using var response = await this._client.Execute(request).ConfigureAwait(false); + return await response.Deserialize().ConfigureAwait(false); } }