From 55d42f1dd83b428aa0f1352bc0ea1402b9c2b811 Mon Sep 17 00:00:00 2001 From: tv Date: Sat, 21 Feb 2026 14:18:13 +0100 Subject: generate initial commit Generate haskell-http-client from running g4f v-7.1.4. Server started like this: python -m g4f --port 8080 --debug Code generated like this: openapi-generator-cli generate \ -i http://localhost:8080/openapi.json \ -g haskell-http-client \ --skip-validate-spec \ -o g4f-client \ --additional-properties=cabalPackage=g4f-client,cabalVersion=7.1.4,baseModule=G4fApi --- .gitignore | 8 + .openapi-generator-ignore | 23 + .openapi-generator/FILES | 23 + .openapi-generator/VERSION | 1 + .travis.yml | 16 + README.md | 203 ++++ Setup.hs | 2 + g4f-client.cabal | 113 ++ git_push.sh | 57 + lib/G4fClient.hs | 31 + lib/G4fClient/API.hs | 19 + lib/G4fClient/API/ApiDefault.hs | 680 ++++++++++++ lib/G4fClient/Client.hs | 223 ++++ lib/G4fClient/Core.hs | 589 +++++++++++ lib/G4fClient/Logging.hs | 33 + lib/G4fClient/LoggingKatip.hs | 117 ++ lib/G4fClient/LoggingMonadLogger.hs | 126 +++ lib/G4fClient/MimeTypes.hs | 225 ++++ lib/G4fClient/Model.hs | 1513 ++++++++++++++++++++++++++ lib/G4fClient/ModelLens.hs | 858 +++++++++++++++ openapi.yaml | 2002 +++++++++++++++++++++++++++++++++++ stack.yaml | 7 + tests/ApproxEq.hs | 81 ++ tests/Instances.hs | 466 ++++++++ tests/PropMime.hs | 51 + tests/Test.hs | 52 + 26 files changed, 7519 insertions(+) create mode 100644 .gitignore create mode 100644 .openapi-generator-ignore create mode 100644 .openapi-generator/FILES create mode 100644 .openapi-generator/VERSION create mode 100644 .travis.yml create mode 100644 README.md create mode 100644 Setup.hs create mode 100644 g4f-client.cabal create mode 100644 git_push.sh create mode 100644 lib/G4fClient.hs create mode 100644 lib/G4fClient/API.hs create mode 100644 lib/G4fClient/API/ApiDefault.hs create mode 100644 lib/G4fClient/Client.hs create mode 100644 lib/G4fClient/Core.hs create mode 100644 lib/G4fClient/Logging.hs create mode 100644 lib/G4fClient/LoggingKatip.hs create mode 100644 lib/G4fClient/LoggingMonadLogger.hs create mode 100644 lib/G4fClient/MimeTypes.hs create mode 100644 lib/G4fClient/Model.hs create mode 100644 lib/G4fClient/ModelLens.hs create mode 100644 openapi.yaml create mode 100644 stack.yaml create mode 100644 tests/ApproxEq.hs create mode 100644 tests/Instances.hs create mode 100644 tests/PropMime.hs create mode 100644 tests/Test.hs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aaed8f8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.stack-work +src/highlight.js +src/style.css +dist +dist-newstyle +cabal.project.local +.cabal-sandbox +cabal.sandbox.config \ No newline at end of file diff --git a/.openapi-generator-ignore b/.openapi-generator-ignore new file mode 100644 index 0000000..7484ee5 --- /dev/null +++ b/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES new file mode 100644 index 0000000..0aa4a4f --- /dev/null +++ b/.openapi-generator/FILES @@ -0,0 +1,23 @@ +.gitignore +.travis.yml +README.md +Setup.hs +g4f-client.cabal +git_push.sh +lib/G4fClient.hs +lib/G4fClient/API.hs +lib/G4fClient/API/ApiDefault.hs +lib/G4fClient/Client.hs +lib/G4fClient/Core.hs +lib/G4fClient/Logging.hs +lib/G4fClient/LoggingKatip.hs +lib/G4fClient/LoggingMonadLogger.hs +lib/G4fClient/MimeTypes.hs +lib/G4fClient/Model.hs +lib/G4fClient/ModelLens.hs +openapi.yaml +stack.yaml +tests/ApproxEq.hs +tests/Instances.hs +tests/PropMime.hs +tests/Test.hs diff --git a/.openapi-generator/VERSION b/.openapi-generator/VERSION new file mode 100644 index 0000000..6328c54 --- /dev/null +++ b/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.17.0 diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..a90f612 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +sudo: false +language: c +addons: + apt: + packages: + - libgmp-dev +before_install: +- mkdir -p ~/.local/bin +- export PATH=$HOME/.local/bin:$PATH +- travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack' +script: +- stack --install-ghc --no-haddock-deps haddock +- stack test +cache: + directories: + - $HOME/.stack diff --git a/README.md b/README.md new file mode 100644 index 0000000..16a5707 --- /dev/null +++ b/README.md @@ -0,0 +1,203 @@ +## OpenAPI Auto-Generated [http-client](https://www.stackage.org/lts-10.0/package/http-client-0.5.7.1) Bindings to `FastAPI` + +The library in `lib` provides auto-generated-from-OpenAPI [http-client](https://www.stackage.org/lts-10.0/package/http-client-0.5.7.1) bindings to the FastAPI API. + +OpenApi Version: 3.1.0 + +## Installation + +Installation follows the standard approach to installing Stack-based projects. + +1. Install the [Haskell `stack` tool](http://docs.haskellstack.org/en/stable/README). +2. To build the package, and generate the documentation (recommended): +``` +stack haddock +``` +which will generate docs for this lib in the `docs` folder. + +To generate the docs in the normal location (to enable hyperlinks to external libs), remove +``` +build: + haddock-arguments: + haddock-args: + - "--odir=./docs" +``` +from the stack.yaml file and run `stack haddock` again. + +3. To run unit tests: +``` +stack test +``` + +## OpenAPI-Generator + +The code generator that produced this library, and which explains how +to obtain and use the openapi-generator cli tool lives at + +https://openapi-generator.tech + +The _generator-name_ argument (`--generator-name`) passed to the cli tool used should be + +``` +haskell-http-client +``` + +### Unsupported OpenAPI Features + +* Model Inheritance + +This is beta software; other cases may not be supported. + +### Codegen "additional properties" parameters + +These options allow some customization of the code generation process. + +**haskell-http-client additional properties:** + +| OPTION | DESCRIPTION | DEFAULT | ACTUAL | +|---------------------------------|-------------------------------------------------------------------------------------------------------------------------------|----------|---------------------------------------| +| allowFromJsonNulls | allow JSON Null during model decoding from JSON | true | true | +| allowNonUniqueOperationIds | allow *different* API modules to contain the same operationId. Each API must be imported qualified | false | false | +| allowToJsonNulls | allow emitting JSON Null during model encoding to JSON | false | false | +| baseModule | Set the base module namespace | | G4fClient | +| cabalPackage | Set the cabal package name, which consists of one or more alphanumeric words separated by hyphens | | g4f-client | +| cabalVersion | Set the cabal version number, consisting of a sequence of one or more integers separated by dots | 0.1.0.0 | 7.1.4 | +| customTestInstanceModule | test module used to provide typeclass instances for types not known by the generator | | | +| configType | Set the name of the type used for configuration | | G4fClientConfig | +| dateFormat | format string used to parse/render a date | %Y-%m-%d | %Y-%m-%d | +| dateTimeFormat | format string used to parse/render a datetime. (Defaults to [formatISO8601Millis][1] when not provided) | | | +| dateTimeParseFormat | overrides the format string used to parse a datetime | | | +| generateEnums | Generate specific datatypes for OpenAPI enums | true | true | +| generateFormUrlEncodedInstances | Generate FromForm/ToForm instances for models used by x-www-form-urlencoded operations (model fields must be primitive types) | true | true | +| generateLenses | Generate Lens optics for Models | true | true | +| generateModelConstructors | Generate smart constructors (only supply required fields) for models | true | true | +| inlineMimeTypes | Inline (hardcode) the content-type and accept parameters on operations, when there is only 1 option | true | true | +| modelDeriving | Additional classes to include in the deriving() clause of Models | | | +| requestType | Set the name of the type used to generate requests | | G4fClientRequest | +| strictFields | Add strictness annotations to all model fields | true | true | +| useKatip | Sets the default value for the UseKatip cabal flag. If true, the katip package provides logging instead of monad-logger | true | true | +| queryExtraUnreserved | Configures additional querystring characters which must not be URI encoded, e.g. '+' or ':' | | | + +[1]: https://www.stackage.org/haddock/lts-9.0/iso8601-time-0.1.4/Data-Time-ISO8601.html#v:formatISO8601Millis + +An example setting _dateTimeFormat_ and _strictFields_: + +``` +java -jar openapi-generator-cli.jar generate -i petstore.yaml -g haskell-http-client -o output/haskell-http-client --additional-properties=dateTimeFormat="%Y-%m-%dT%H:%M:%S%Q%z" --additional-properties=strictFields=false +``` + +View the full list of Codegen "config option" parameters with the command: + +``` +java -jar openapi-generator-cli.jar config-help -g haskell-http-client +``` + +## Usage Notes + +### Example Petstore Haddock documentation + +An example of the generated haddock documentation targeting the server http://petstore.swagger.io/ (Petstore) can be found [here][2] + +[2]: https://hackage.haskell.org/package/swagger-petstore + +### Example Petstore App + +An example application using the auto-generated haskell-http-client bindings for the server http://petstore.swagger.io/ can be found [here][3] + +[3]: https://github.com/openapitools/openapi-generator/tree/master/samples/client/petstore/haskell-http-client/example-app + +This library is intended to be imported qualified. + +### Modules + +| MODULE | NOTES | +| ------------------- | --------------------------------------------------- | +| G4fClient.Client | use the "dispatch" functions to send requests | +| G4fClient.Core | core functions, config and request types | +| G4fClient.API | construct api requests | +| G4fClient.Model | describes api models | +| G4fClient.MimeTypes | encoding/decoding MIME types (content-types/accept) | +| G4fClient.ModelLens | lenses for model fields | +| G4fClient.Logging | logging functions and utils | + + +### MimeTypes + +This library adds type safety around what OpenAPI specifies as +Produces and Consumes for each Operation (e.g. the list of MIME types an +Operation can Produce (using 'accept' headers) and Consume (using 'content-type' headers). + +For example, if there is an Operation named _addFoo_, there will be a +data type generated named _AddFoo_ (note the capitalization), which +describes additional constraints and actions on the _addFoo_ operation +via its typeclass instances. These typeclass instances can be viewed +in GHCi or via the Haddocks. + +* required parameters are included as function arguments to _addFoo_ +* optional non-body parameters are included by using `applyOptionalParam` +* optional body parameters are set by using `setBodyParam` + +Example code generated for pretend _addFoo_ operation: + +```haskell +data AddFoo +instance Consumes AddFoo MimeJSON +instance Produces AddFoo MimeJSON +instance Produces AddFoo MimeXML +instance HasBodyParam AddFoo FooModel +instance HasOptionalParam AddFoo FooName +instance HasOptionalParam AddFoo FooId +``` + +this would indicate that: + +* the _addFoo_ operation can consume JSON +* the _addFoo_ operation produces JSON or XML, depending on the argument passed to the dispatch function +* the _addFoo_ operation can set it's body param of _FooModel_ via `setBodyParam` +* the _addFoo_ operation can set 2 different optional parameters via `applyOptionalParam` + +If the OpenAPI spec doesn't declare it can accept or produce a certain +MIME type for a given Operation, you should either add a Produces or +Consumes instance for the desired MIME types (assuming the server +supports it), use `dispatchLbsUnsafe` or modify the OpenAPI spec and +run the generator again. + +New MIME type instances can be added via MimeType/MimeRender/MimeUnrender + +Only JSON instances are generated by default, and in some case +x-www-form-urlencoded instances (FromFrom, ToForm) will also be +generated if the model fields are primitive types, and there are +Operations using x-www-form-urlencoded which use those models. + +### Authentication + +A haskell data type will be generated for each OpenAPI authentication type. + +If for example the AuthMethod `AuthOAuthFoo` is generated for OAuth operations, then +`addAuthMethod` should be used to add the AuthMethod config. + +When a request is dispatched, if a matching auth method is found in +the config, it will be applied to the request. + +### Example + +```haskell +mgr <- newManager defaultManagerSettings +config0 <- withStdoutLogging =<< newConfig +let config = config0 + `addAuthMethod` AuthOAuthFoo "secret-key" + +let addFooRequest = + addFoo + (ContentType MimeJSON) + (Accept MimeXML) + (ParamBar paramBar) + (ParamQux paramQux) + modelBaz + `applyOptionalParam` FooId 1 + `applyOptionalParam` FooName "name" + `setHeader` [("qux_header","xxyy")] +addFooResult <- dispatchMime mgr config addFooRequest +``` + +See the example app and the haddocks for details. diff --git a/Setup.hs b/Setup.hs new file mode 100644 index 0000000..9a994af --- /dev/null +++ b/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/g4f-client.cabal b/g4f-client.cabal new file mode 100644 index 0000000..2bc5ffe --- /dev/null +++ b/g4f-client.cabal @@ -0,0 +1,113 @@ +name: g4f-client +version: 7.1.4 +synopsis: Auto-generated g4f-client API Client +description: . + Client library for calling the FastAPI API based on http-client. + . + host: localhost + . + base path: http://localhost + . + FastAPI API version: 0.1.0 + . + OpenAPI version: 3.1.0 + . + Generator version: 7.17.0 + . +category: Web +homepage: https://openapi-generator.tech +author: Author Name Here +maintainer: author.name@email.com +copyright: YEAR - AUTHOR +license: UnspecifiedLicense +build-type: Simple +cabal-version: >= 1.10 + +extra-source-files: + README.md + openapi.yaml + +Flag UseKatip + Description: Use the katip package to provide logging (if false, use the default monad-logger package) + Default: True + Manual: True + +library + hs-source-dirs: + lib + ghc-options: -Wall -funbox-strict-fields + build-depends: + aeson >=1.0 && <3.0 + , base >=4.7 && <5.0 + , base64-bytestring >1.0 && <2.0 + , bytestring >=0.10.0 + , case-insensitive + , containers >=0.5.0.0 && <0.8 + , deepseq >= 1.4 && <1.6 + , exceptions >= 0.4 + , http-api-data >= 0.3.4 && <0.6 + , http-client >=0.5 && <0.8 + , http-client-tls + , http-media >= 0.4 && < 0.9 + , http-types >=0.8 && <0.13 + , iso8601-time >=0.1.3 && <0.2.0 + , microlens >= 0.4.3 + , mtl >=2.2.1 + , network >=2.6.2 && <3.9 + , random >=1.1 + , safe-exceptions <0.2 + , text >=0.11 && <3 + , time >=1.5 + , transformers >=0.4.0.0 + , unordered-containers + , vector >=0.10.9 && <0.14 + other-modules: + Paths_g4f_client + exposed-modules: + G4fClient + G4fClient.API + G4fClient.API.ApiDefault + G4fClient.Client + G4fClient.Core + G4fClient.Logging + G4fClient.MimeTypes + G4fClient.Model + G4fClient.ModelLens + default-language: Haskell2010 + + if flag(UseKatip) + build-depends: katip >=0.8 && < 1.0 + other-modules: G4fClient.LoggingKatip + cpp-options: -DUSE_KATIP + else + build-depends: monad-logger >=0.3 && <0.4 + other-modules: G4fClient.LoggingMonadLogger + cpp-options: -DUSE_MONAD_LOGGER + +test-suite tests + type: exitcode-stdio-1.0 + main-is: Test.hs + hs-source-dirs: + tests + ghc-options: -Wall -fno-warn-orphans + build-depends: + g4f-client + , QuickCheck + , aeson + , base >=4.7 && <5.0 + , bytestring >=0.10.0 + , containers + , hspec >=1.8 + , iso8601-time + , mtl >=2.2.1 + , semigroups + , text + , time + , transformers >=0.4.0.0 + , unordered-containers + , vector + other-modules: + ApproxEq + Instances + PropMime + default-language: Haskell2010 diff --git a/git_push.sh b/git_push.sh new file mode 100644 index 0000000..f53a75d --- /dev/null +++ b/git_push.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 +git_host=$4 + +if [ "$git_host" = "" ]; then + git_host="github.com" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=$(git remote) +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' diff --git a/lib/G4fClient.hs b/lib/G4fClient.hs new file mode 100644 index 0000000..711c375 --- /dev/null +++ b/lib/G4fClient.hs @@ -0,0 +1,31 @@ +{- + FastAPI + + No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + + OpenAPI Version: 3.1.0 + FastAPI API version: 0.1.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) +-} + +{-| +Module : G4fClient +-} + +module G4fClient + ( module G4fClient.API + , module G4fClient.Client + , module G4fClient.Core + , module G4fClient.Logging + , module G4fClient.MimeTypes + , module G4fClient.Model + , module G4fClient.ModelLens + ) where + +import G4fClient.API +import G4fClient.Client +import G4fClient.Core +import G4fClient.Logging +import G4fClient.MimeTypes +import G4fClient.Model +import G4fClient.ModelLens \ No newline at end of file diff --git a/lib/G4fClient/API.hs b/lib/G4fClient/API.hs new file mode 100644 index 0000000..0ec10da --- /dev/null +++ b/lib/G4fClient/API.hs @@ -0,0 +1,19 @@ +{- + FastAPI + + No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + + OpenAPI Version: 3.1.0 + FastAPI API version: 0.1.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) +-} + +{-| +Module : G4fClient.API +-} + +module G4fClient.API + ( module G4fClient.API.ApiDefault + ) where + +import G4fClient.API.ApiDefault \ No newline at end of file diff --git a/lib/G4fClient/API/ApiDefault.hs b/lib/G4fClient/API/ApiDefault.hs new file mode 100644 index 0000000..3991f71 --- /dev/null +++ b/lib/G4fClient/API/ApiDefault.hs @@ -0,0 +1,680 @@ +{- + FastAPI + + No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + + OpenAPI Version: 3.1.0 + FastAPI API version: 0.1.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) +-} + +{-| +Module : G4fClient.API.ApiDefault +-} + +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE MonoLocalBinds #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE OverloadedStrings #-} +{-# OPTIONS_GHC -fno-warn-name-shadowing -fno-warn-unused-binds -fno-warn-unused-imports #-} + +module G4fClient.API.ApiDefault where + +import G4fClient.Core +import G4fClient.MimeTypes +import G4fClient.Model as M + +import qualified Data.Aeson as A +import qualified Data.ByteString as B +import qualified Data.ByteString.Lazy as BL +import qualified Data.Data as P (Typeable, TypeRep, typeOf, typeRep) +import qualified Data.Foldable as P +import qualified Data.Map as Map +import qualified Data.Maybe as P +import qualified Data.Proxy as P (Proxy(..)) +import qualified Data.Set as Set +import qualified Data.String as P +import qualified Data.Text as T +import qualified Data.Text.Encoding as T +import qualified Data.Text.Lazy as TL +import qualified Data.Text.Lazy.Encoding as TL +import qualified Data.Time as TI +import qualified Network.HTTP.Client.MultipartFormData as NH +import qualified Network.HTTP.Media as ME +import qualified Network.HTTP.Types as NH +import qualified Web.FormUrlEncoded as WH +import qualified Web.HttpApiData as WH + +import Data.Text (Text) +import GHC.Base ((<|>)) + +import Prelude ((==),(/=),($), (.),(<$>),(<*>),(>>=),Maybe(..),Bool(..),Char,Double,FilePath,Float,Int,Integer,String,fmap,undefined,mempty,maybe,pure,Monad,Applicative,Functor) +import qualified Prelude as P + +-- * Operations + + +-- ** Default + +-- *** chatCompletionsApiProviderChatCompletionsPost + +-- | @POST \/api\/{provider}\/chat\/completions@ +-- +-- Chat Completions +-- +-- AuthMethod: 'AuthBasicHTTPBearer' +-- +chatCompletionsApiProviderChatCompletionsPost + :: (Consumes ChatCompletionsApiProviderChatCompletionsPost MimeJSON, MimeRender MimeJSON ChatCompletionsConfig) + => ChatCompletionsConfig -- ^ "chatCompletionsConfig" + -> Provider -- ^ "provider" + -> G4fClientRequest ChatCompletionsApiProviderChatCompletionsPost MimeJSON ChatCompletion MimeJSON +chatCompletionsApiProviderChatCompletionsPost chatCompletionsConfig (Provider provider) = + _mkRequest "POST" ["/api/",toPath provider,"/chat/completions"] + `_hasAuthType` (P.Proxy :: P.Proxy AuthBasicHTTPBearer) + `setBodyParam` chatCompletionsConfig + +data ChatCompletionsApiProviderChatCompletionsPost +instance HasBodyParam ChatCompletionsApiProviderChatCompletionsPost ChatCompletionsConfig +instance HasOptionalParam ChatCompletionsApiProviderChatCompletionsPost ConversationId where + applyOptionalParam req (ConversationId xs) = + req `addQuery` toQuery ("conversation_id", Just xs) +instance HasOptionalParam ChatCompletionsApiProviderChatCompletionsPost XUser where + applyOptionalParam req (XUser xs) = + req `addHeader` toHeader ("x-user", xs) + +-- | @application/json@ +instance Consumes ChatCompletionsApiProviderChatCompletionsPost MimeJSON + +-- | @application/json@ +instance Produces ChatCompletionsApiProviderChatCompletionsPost MimeJSON + + +-- *** chatCompletionsApiProviderConversationIdChatCompletionsPost + +-- | @POST \/api\/{provider}\/{conversation_id}\/chat\/completions@ +-- +-- Chat Completions +-- +-- AuthMethod: 'AuthBasicHTTPBearer' +-- +chatCompletionsApiProviderConversationIdChatCompletionsPost + :: (Consumes ChatCompletionsApiProviderConversationIdChatCompletionsPost MimeJSON, MimeRender MimeJSON ChatCompletionsConfig) + => ChatCompletionsConfig -- ^ "chatCompletionsConfig" + -> Provider -- ^ "provider" + -> ConversationId -- ^ "conversationId" + -> G4fClientRequest ChatCompletionsApiProviderConversationIdChatCompletionsPost MimeJSON ChatCompletion MimeJSON +chatCompletionsApiProviderConversationIdChatCompletionsPost chatCompletionsConfig (Provider provider) (ConversationId conversationId) = + _mkRequest "POST" ["/api/",toPath provider,"/",toPath conversationId,"/chat/completions"] + `_hasAuthType` (P.Proxy :: P.Proxy AuthBasicHTTPBearer) + `setBodyParam` chatCompletionsConfig + +data ChatCompletionsApiProviderConversationIdChatCompletionsPost +instance HasBodyParam ChatCompletionsApiProviderConversationIdChatCompletionsPost ChatCompletionsConfig +instance HasOptionalParam ChatCompletionsApiProviderConversationIdChatCompletionsPost XUser where + applyOptionalParam req (XUser xs) = + req `addHeader` toHeader ("x-user", xs) + +-- | @application/json@ +instance Consumes ChatCompletionsApiProviderConversationIdChatCompletionsPost MimeJSON + +-- | @application/json@ +instance Produces ChatCompletionsApiProviderConversationIdChatCompletionsPost MimeJSON + + +-- *** chatCompletionsV1ChatCompletionsPost + +-- | @POST \/v1\/chat\/completions@ +-- +-- Chat Completions +-- +-- AuthMethod: 'AuthBasicHTTPBearer' +-- +chatCompletionsV1ChatCompletionsPost + :: (Consumes ChatCompletionsV1ChatCompletionsPost MimeJSON, MimeRender MimeJSON ChatCompletionsConfig) + => ChatCompletionsConfig -- ^ "chatCompletionsConfig" + -> G4fClientRequest ChatCompletionsV1ChatCompletionsPost MimeJSON ChatCompletion MimeJSON +chatCompletionsV1ChatCompletionsPost chatCompletionsConfig = + _mkRequest "POST" ["/v1/chat/completions"] + `_hasAuthType` (P.Proxy :: P.Proxy AuthBasicHTTPBearer) + `setBodyParam` chatCompletionsConfig + +data ChatCompletionsV1ChatCompletionsPost +instance HasBodyParam ChatCompletionsV1ChatCompletionsPost ChatCompletionsConfig +instance HasOptionalParam ChatCompletionsV1ChatCompletionsPost Provider where + applyOptionalParam req (Provider xs) = + req `addQuery` toQuery ("provider", Just xs) +instance HasOptionalParam ChatCompletionsV1ChatCompletionsPost ConversationId where + applyOptionalParam req (ConversationId xs) = + req `addQuery` toQuery ("conversation_id", Just xs) +instance HasOptionalParam ChatCompletionsV1ChatCompletionsPost XUser where + applyOptionalParam req (XUser xs) = + req `addHeader` toHeader ("x-user", xs) + +-- | @application/json@ +instance Consumes ChatCompletionsV1ChatCompletionsPost MimeJSON + +-- | @application/json@ +instance Produces ChatCompletionsV1ChatCompletionsPost MimeJSON + + +-- *** convertApiMarkitdownPost + +-- | @POST \/api\/markitdown@ +-- +-- Convert +-- +convertApiMarkitdownPost + :: (Consumes ConvertApiMarkitdownPost MimeMultipartFormData) + => File -- ^ "file" + -> G4fClientRequest ConvertApiMarkitdownPost MimeMultipartFormData TranscriptionResponseModel MimeJSON +convertApiMarkitdownPost (File file) = + _mkRequest "POST" ["/api/markitdown"] + `_addMultiFormPart` NH.partFileSource "file" file + +data ConvertApiMarkitdownPost +instance HasOptionalParam ConvertApiMarkitdownPost Model where + applyOptionalParam req (Model xs) = + req `_addMultiFormPart` NH.partLBS "model" (mimeRender' MimeMultipartFormData xs) +instance HasOptionalParam ConvertApiMarkitdownPost Provider where + applyOptionalParam req (Provider xs) = + req `_addMultiFormPart` NH.partLBS "provider" (mimeRender' MimeMultipartFormData xs) +instance HasOptionalParam ConvertApiMarkitdownPost Prompt where + applyOptionalParam req (Prompt xs) = + req `_addMultiFormPart` NH.partLBS "prompt" (mimeRender' MimeMultipartFormData xs) +instance HasOptionalParam ConvertApiMarkitdownPost PathProvider where + applyOptionalParam req (PathProvider xs) = + req `addQuery` toQuery ("path_provider", Just xs) + +-- | @multipart/form-data@ +instance Consumes ConvertApiMarkitdownPost MimeMultipartFormData + +-- | @application/json@ +instance Produces ConvertApiMarkitdownPost MimeJSON + + +-- *** convertApiPathProviderAudioTranscriptionsPost + +-- | @POST \/api\/{path_provider}\/audio\/transcriptions@ +-- +-- Convert +-- +convertApiPathProviderAudioTranscriptionsPost + :: (Consumes ConvertApiPathProviderAudioTranscriptionsPost MimeMultipartFormData) + => File -- ^ "file" + -> PathProvider -- ^ "pathProvider" + -> G4fClientRequest ConvertApiPathProviderAudioTranscriptionsPost MimeMultipartFormData TranscriptionResponseModel MimeJSON +convertApiPathProviderAudioTranscriptionsPost (File file) (PathProvider pathProvider) = + _mkRequest "POST" ["/api/",toPath pathProvider,"/audio/transcriptions"] + `_addMultiFormPart` NH.partFileSource "file" file + +data ConvertApiPathProviderAudioTranscriptionsPost +instance HasOptionalParam ConvertApiPathProviderAudioTranscriptionsPost Model where + applyOptionalParam req (Model xs) = + req `_addMultiFormPart` NH.partLBS "model" (mimeRender' MimeMultipartFormData xs) +instance HasOptionalParam ConvertApiPathProviderAudioTranscriptionsPost Provider where + applyOptionalParam req (Provider xs) = + req `_addMultiFormPart` NH.partLBS "provider" (mimeRender' MimeMultipartFormData xs) +instance HasOptionalParam ConvertApiPathProviderAudioTranscriptionsPost Prompt where + applyOptionalParam req (Prompt xs) = + req `_addMultiFormPart` NH.partLBS "prompt" (mimeRender' MimeMultipartFormData xs) + +-- | @multipart/form-data@ +instance Consumes ConvertApiPathProviderAudioTranscriptionsPost MimeMultipartFormData + +-- | @application/json@ +instance Produces ConvertApiPathProviderAudioTranscriptionsPost MimeJSON + + +-- *** convertV1AudioTranscriptionsPost + +-- | @POST \/v1\/audio\/transcriptions@ +-- +-- Convert +-- +convertV1AudioTranscriptionsPost + :: (Consumes ConvertV1AudioTranscriptionsPost MimeMultipartFormData) + => File -- ^ "file" + -> G4fClientRequest ConvertV1AudioTranscriptionsPost MimeMultipartFormData TranscriptionResponseModel MimeJSON +convertV1AudioTranscriptionsPost (File file) = + _mkRequest "POST" ["/v1/audio/transcriptions"] + `_addMultiFormPart` NH.partFileSource "file" file + +data ConvertV1AudioTranscriptionsPost +instance HasOptionalParam ConvertV1AudioTranscriptionsPost Model where + applyOptionalParam req (Model xs) = + req `_addMultiFormPart` NH.partLBS "model" (mimeRender' MimeMultipartFormData xs) +instance HasOptionalParam ConvertV1AudioTranscriptionsPost Provider where + applyOptionalParam req (Provider xs) = + req `_addMultiFormPart` NH.partLBS "provider" (mimeRender' MimeMultipartFormData xs) +instance HasOptionalParam ConvertV1AudioTranscriptionsPost Prompt where + applyOptionalParam req (Prompt xs) = + req `_addMultiFormPart` NH.partLBS "prompt" (mimeRender' MimeMultipartFormData xs) +instance HasOptionalParam ConvertV1AudioTranscriptionsPost PathProvider where + applyOptionalParam req (PathProvider xs) = + req `addQuery` toQuery ("path_provider", Just xs) + +-- | @multipart/form-data@ +instance Consumes ConvertV1AudioTranscriptionsPost MimeMultipartFormData + +-- | @application/json@ +instance Produces ConvertV1AudioTranscriptionsPost MimeJSON + + +-- *** generateImageApiProviderImagesGenerationsPost + +-- | @POST \/api\/{provider}\/images\/generations@ +-- +-- Generate Image +-- +-- AuthMethod: 'AuthBasicHTTPBearer' +-- +generateImageApiProviderImagesGenerationsPost + :: (Consumes GenerateImageApiProviderImagesGenerationsPost MimeJSON, MimeRender MimeJSON ImageGenerationConfig) + => ImageGenerationConfig -- ^ "imageGenerationConfig" + -> Provider -- ^ "provider" + -> G4fClientRequest GenerateImageApiProviderImagesGenerationsPost MimeJSON ImagesResponse MimeJSON +generateImageApiProviderImagesGenerationsPost imageGenerationConfig (Provider provider) = + _mkRequest "POST" ["/api/",toPath provider,"/images/generations"] + `_hasAuthType` (P.Proxy :: P.Proxy AuthBasicHTTPBearer) + `setBodyParam` imageGenerationConfig + +data GenerateImageApiProviderImagesGenerationsPost +instance HasBodyParam GenerateImageApiProviderImagesGenerationsPost ImageGenerationConfig + +-- | @application/json@ +instance Consumes GenerateImageApiProviderImagesGenerationsPost MimeJSON + +-- | @application/json@ +instance Produces GenerateImageApiProviderImagesGenerationsPost MimeJSON + + +-- *** generateImageV1ImagesGeneratePost + +-- | @POST \/v1\/images\/generate@ +-- +-- Generate Image +-- +-- AuthMethod: 'AuthBasicHTTPBearer' +-- +generateImageV1ImagesGeneratePost + :: (Consumes GenerateImageV1ImagesGeneratePost MimeJSON, MimeRender MimeJSON ImageGenerationConfig) + => ImageGenerationConfig -- ^ "imageGenerationConfig" + -> G4fClientRequest GenerateImageV1ImagesGeneratePost MimeJSON ImagesResponse MimeJSON +generateImageV1ImagesGeneratePost imageGenerationConfig = + _mkRequest "POST" ["/v1/images/generate"] + `_hasAuthType` (P.Proxy :: P.Proxy AuthBasicHTTPBearer) + `setBodyParam` imageGenerationConfig + +data GenerateImageV1ImagesGeneratePost +instance HasBodyParam GenerateImageV1ImagesGeneratePost ImageGenerationConfig +instance HasOptionalParam GenerateImageV1ImagesGeneratePost Provider where + applyOptionalParam req (Provider xs) = + req `addQuery` toQuery ("provider", Just xs) + +-- | @application/json@ +instance Consumes GenerateImageV1ImagesGeneratePost MimeJSON + +-- | @application/json@ +instance Produces GenerateImageV1ImagesGeneratePost MimeJSON + + +-- *** generateImageV1ImagesGenerationsPost + +-- | @POST \/v1\/images\/generations@ +-- +-- Generate Image +-- +-- AuthMethod: 'AuthBasicHTTPBearer' +-- +generateImageV1ImagesGenerationsPost + :: (Consumes GenerateImageV1ImagesGenerationsPost MimeJSON, MimeRender MimeJSON ImageGenerationConfig) + => ImageGenerationConfig -- ^ "imageGenerationConfig" + -> G4fClientRequest GenerateImageV1ImagesGenerationsPost MimeJSON ImagesResponse MimeJSON +generateImageV1ImagesGenerationsPost imageGenerationConfig = + _mkRequest "POST" ["/v1/images/generations"] + `_hasAuthType` (P.Proxy :: P.Proxy AuthBasicHTTPBearer) + `setBodyParam` imageGenerationConfig + +data GenerateImageV1ImagesGenerationsPost +instance HasBodyParam GenerateImageV1ImagesGenerationsPost ImageGenerationConfig +instance HasOptionalParam GenerateImageV1ImagesGenerationsPost Provider where + applyOptionalParam req (Provider xs) = + req `addQuery` toQuery ("provider", Just xs) + +-- | @application/json@ +instance Consumes GenerateImageV1ImagesGenerationsPost MimeJSON + +-- | @application/json@ +instance Produces GenerateImageV1ImagesGenerationsPost MimeJSON + + +-- *** generateImageV1MediaGeneratePost + +-- | @POST \/v1\/media\/generate@ +-- +-- Generate Image +-- +-- AuthMethod: 'AuthBasicHTTPBearer' +-- +generateImageV1MediaGeneratePost + :: (Consumes GenerateImageV1MediaGeneratePost MimeJSON, MimeRender MimeJSON ImageGenerationConfig) + => ImageGenerationConfig -- ^ "imageGenerationConfig" + -> G4fClientRequest GenerateImageV1MediaGeneratePost MimeJSON ImagesResponse MimeJSON +generateImageV1MediaGeneratePost imageGenerationConfig = + _mkRequest "POST" ["/v1/media/generate"] + `_hasAuthType` (P.Proxy :: P.Proxy AuthBasicHTTPBearer) + `setBodyParam` imageGenerationConfig + +data GenerateImageV1MediaGeneratePost +instance HasBodyParam GenerateImageV1MediaGeneratePost ImageGenerationConfig +instance HasOptionalParam GenerateImageV1MediaGeneratePost Provider where + applyOptionalParam req (Provider xs) = + req `addQuery` toQuery ("provider", Just xs) + +-- | @application/json@ +instance Consumes GenerateImageV1MediaGeneratePost MimeJSON + +-- | @application/json@ +instance Produces GenerateImageV1MediaGeneratePost MimeJSON + + +-- *** generateSpeechApiProviderAudioSpeechPost + +-- | @POST \/api\/{provider}\/audio\/speech@ +-- +-- Generate Speech +-- +-- AuthMethod: 'AuthBasicHTTPBearer' +-- +generateSpeechApiProviderAudioSpeechPost + :: (Consumes GenerateSpeechApiProviderAudioSpeechPost MimeJSON, MimeRender MimeJSON AudioSpeechConfig) + => Accept accept -- ^ request accept ('MimeType') + -> AudioSpeechConfig -- ^ "audioSpeechConfig" + -> Provider -- ^ "provider" + -> G4fClientRequest GenerateSpeechApiProviderAudioSpeechPost MimeJSON AnyType accept +generateSpeechApiProviderAudioSpeechPost _ audioSpeechConfig (Provider provider) = + _mkRequest "POST" ["/api/",toPath provider,"/audio/speech"] + `_hasAuthType` (P.Proxy :: P.Proxy AuthBasicHTTPBearer) + `setBodyParam` audioSpeechConfig + +data GenerateSpeechApiProviderAudioSpeechPost +instance HasBodyParam GenerateSpeechApiProviderAudioSpeechPost AudioSpeechConfig + +-- | @application/json@ +instance Consumes GenerateSpeechApiProviderAudioSpeechPost MimeJSON + +-- | @application/json@ +instance Produces GenerateSpeechApiProviderAudioSpeechPost MimeJSON +-- | @audio/*@ +instance Produces GenerateSpeechApiProviderAudioSpeechPost MimeAudio + + +-- *** generateSpeechV1AudioSpeechPost + +-- | @POST \/v1\/audio\/speech@ +-- +-- Generate Speech +-- +-- AuthMethod: 'AuthBasicHTTPBearer' +-- +generateSpeechV1AudioSpeechPost + :: (Consumes GenerateSpeechV1AudioSpeechPost MimeJSON, MimeRender MimeJSON AudioSpeechConfig) + => Accept accept -- ^ request accept ('MimeType') + -> AudioSpeechConfig -- ^ "audioSpeechConfig" + -> G4fClientRequest GenerateSpeechV1AudioSpeechPost MimeJSON AnyType accept +generateSpeechV1AudioSpeechPost _ audioSpeechConfig = + _mkRequest "POST" ["/v1/audio/speech"] + `_hasAuthType` (P.Proxy :: P.Proxy AuthBasicHTTPBearer) + `setBodyParam` audioSpeechConfig + +data GenerateSpeechV1AudioSpeechPost +instance HasBodyParam GenerateSpeechV1AudioSpeechPost AudioSpeechConfig +instance HasOptionalParam GenerateSpeechV1AudioSpeechPost Provider where + applyOptionalParam req (Provider xs) = + req `addQuery` toQuery ("provider", Just xs) + +-- | @application/json@ +instance Consumes GenerateSpeechV1AudioSpeechPost MimeJSON + +-- | @application/json@ +instance Produces GenerateSpeechV1AudioSpeechPost MimeJSON +-- | @audio/*@ +instance Produces GenerateSpeechV1AudioSpeechPost MimeAudio + + +-- *** getMediaImagesFilenameGet + +-- | @GET \/images\/{filename}@ +-- +-- Get Media +-- +getMediaImagesFilenameGet + :: Accept accept -- ^ request accept ('MimeType') + -> Filename -- ^ "filename" + -> G4fClientRequest GetMediaImagesFilenameGet MimeNoContent AnyType accept +getMediaImagesFilenameGet _ (Filename filename) = + _mkRequest "GET" ["/images/",toPath filename] + +data GetMediaImagesFilenameGet +instance HasOptionalParam GetMediaImagesFilenameGet Thumbnail where + applyOptionalParam req (Thumbnail xs) = + req `addQuery` toQuery ("thumbnail", Just xs) +-- | @image/*@ +instance Produces GetMediaImagesFilenameGet MimeImage +-- | @application/json@ +instance Produces GetMediaImagesFilenameGet MimeJSON + + +-- *** getMediaMediaFilenameGet + +-- | @GET \/media\/{filename}@ +-- +-- Get Media +-- +getMediaMediaFilenameGet + :: Accept accept -- ^ request accept ('MimeType') + -> Filename -- ^ "filename" + -> G4fClientRequest GetMediaMediaFilenameGet MimeNoContent AnyType accept +getMediaMediaFilenameGet _ (Filename filename) = + _mkRequest "GET" ["/media/",toPath filename] + +data GetMediaMediaFilenameGet +instance HasOptionalParam GetMediaMediaFilenameGet Thumbnail where + applyOptionalParam req (Thumbnail xs) = + req `addQuery` toQuery ("thumbnail", Just xs) +-- | @image/*@ +instance Produces GetMediaMediaFilenameGet MimeImage +-- | @application/json@ +instance Produces GetMediaMediaFilenameGet MimeJSON +-- | @audio/*@ +instance Produces GetMediaMediaFilenameGet MimeAudio + + +-- *** getMediaThumbnailThumbnailFilenameGet + +-- | @GET \/thumbnail\/{filename}@ +-- +-- Get Media Thumbnail +-- +getMediaThumbnailThumbnailFilenameGet + :: Accept accept -- ^ request accept ('MimeType') + -> FilenameText -- ^ "filename" + -> G4fClientRequest GetMediaThumbnailThumbnailFilenameGet MimeNoContent AnyType accept +getMediaThumbnailThumbnailFilenameGet _ (FilenameText filename) = + _mkRequest "GET" ["/thumbnail/",toPath filename] + +data GetMediaThumbnailThumbnailFilenameGet +-- | @image/*@ +instance Produces GetMediaThumbnailThumbnailFilenameGet MimeImage +-- | @application/json@ +instance Produces GetMediaThumbnailThumbnailFilenameGet MimeJSON +-- | @audio/*@ +instance Produces GetMediaThumbnailThumbnailFilenameGet MimeAudio + + +-- *** modelInfoV1ModelsModelNameGet + +-- | @GET \/v1\/models\/{model_name}@ +-- +-- Model Info +-- +modelInfoV1ModelsModelNameGet + :: ModelName -- ^ "modelName" + -> G4fClientRequest ModelInfoV1ModelsModelNameGet MimeNoContent ModelResponseModel MimeJSON +modelInfoV1ModelsModelNameGet (ModelName modelName) = + _mkRequest "GET" ["/v1/models/",toPath modelName] + +data ModelInfoV1ModelsModelNameGet +-- | @application/json@ +instance Produces ModelInfoV1ModelsModelNameGet MimeJSON + + +-- *** modelInfoV1ModelsModelNamePost + +-- | @POST \/v1\/models\/{model_name}@ +-- +-- Model Info +-- +modelInfoV1ModelsModelNamePost + :: ModelName -- ^ "modelName" + -> G4fClientRequest ModelInfoV1ModelsModelNamePost MimeNoContent ModelResponseModel MimeJSON +modelInfoV1ModelsModelNamePost (ModelName modelName) = + _mkRequest "POST" ["/v1/models/",toPath modelName] + +data ModelInfoV1ModelsModelNamePost +-- | @application/json@ +instance Produces ModelInfoV1ModelsModelNamePost MimeJSON + + +-- *** modelsApiProviderModelsGet + +-- | @GET \/api\/{provider}\/models@ +-- +-- Models +-- +-- AuthMethod: 'AuthBasicHTTPBearer' +-- +modelsApiProviderModelsGet + :: Provider -- ^ "provider" + -> G4fClientRequest ModelsApiProviderModelsGet MimeNoContent [ModelResponseModel] MimeJSON +modelsApiProviderModelsGet (Provider provider) = + _mkRequest "GET" ["/api/",toPath provider,"/models"] + `_hasAuthType` (P.Proxy :: P.Proxy AuthBasicHTTPBearer) + +data ModelsApiProviderModelsGet +-- | @application/json@ +instance Produces ModelsApiProviderModelsGet MimeJSON + + +-- *** modelsV1ModelsGet + +-- | @GET \/v1\/models@ +-- +-- Models +-- +modelsV1ModelsGet + :: G4fClientRequest ModelsV1ModelsGet MimeNoContent [ModelResponseModel] MimeJSON +modelsV1ModelsGet = + _mkRequest "GET" ["/v1/models"] + +data ModelsV1ModelsGet +-- | @application/json@ +instance Produces ModelsV1ModelsGet MimeJSON + + +-- *** providerQuotaApiProviderQuotaGet + +-- | @GET \/api\/{provider}\/quota@ +-- +-- Provider Quota +-- +-- AuthMethod: 'AuthBasicHTTPBearer' +-- +providerQuotaApiProviderQuotaGet + :: Provider -- ^ "provider" + -> G4fClientRequest ProviderQuotaApiProviderQuotaGet MimeNoContent AnyType MimeJSON +providerQuotaApiProviderQuotaGet (Provider provider) = + _mkRequest "GET" ["/api/",toPath provider,"/quota"] + `_hasAuthType` (P.Proxy :: P.Proxy AuthBasicHTTPBearer) + +data ProviderQuotaApiProviderQuotaGet +-- | @application/json@ +instance Produces ProviderQuotaApiProviderQuotaGet MimeJSON + + +-- *** providersInfoV1ProvidersProviderGet + +-- | @GET \/v1\/providers\/{provider}@ +-- +-- Providers Info +-- +providersInfoV1ProvidersProviderGet + :: Provider -- ^ "provider" + -> G4fClientRequest ProvidersInfoV1ProvidersProviderGet MimeNoContent ProviderResponseDetailModel MimeJSON +providersInfoV1ProvidersProviderGet (Provider provider) = + _mkRequest "GET" ["/v1/providers/",toPath provider] + +data ProvidersInfoV1ProvidersProviderGet +-- | @application/json@ +instance Produces ProvidersInfoV1ProvidersProviderGet MimeJSON + + +-- *** providersV1ProvidersGet + +-- | @GET \/v1\/providers@ +-- +-- Providers +-- +providersV1ProvidersGet + :: G4fClientRequest ProvidersV1ProvidersGet MimeNoContent [ProviderResponseModel] MimeJSON +providersV1ProvidersGet = + _mkRequest "GET" ["/v1/providers"] + +data ProvidersV1ProvidersGet +-- | @application/json@ +instance Produces ProvidersV1ProvidersGet MimeJSON + + +-- *** readRootV1V1Get + +-- | @GET \/v1@ +-- +-- Read Root V1 +-- +readRootV1V1Get + :: G4fClientRequest ReadRootV1V1Get MimeNoContent AnyType MimeJSON +readRootV1V1Get = + _mkRequest "GET" ["/v1"] + +data ReadRootV1V1Get +-- | @application/json@ +instance Produces ReadRootV1V1Get MimeJSON + + +-- *** uploadCookiesV1UploadCookiesPost + +-- | @POST \/v1\/upload_cookies@ +-- +-- Upload Cookies +-- +-- AuthMethod: 'AuthBasicHTTPBearer' +-- +uploadCookiesV1UploadCookiesPost + :: (Consumes UploadCookiesV1UploadCookiesPost MimeMultipartFormData) + => Files -- ^ "files" + -> G4fClientRequest UploadCookiesV1UploadCookiesPost MimeMultipartFormData [FileResponseModel] MimeJSON +uploadCookiesV1UploadCookiesPost (Files files) = + _mkRequest "POST" ["/v1/upload_cookies"] + `_hasAuthType` (P.Proxy :: P.Proxy AuthBasicHTTPBearer) + `_addMultiFormPart` NH.partFileSource "files" files + +data UploadCookiesV1UploadCookiesPost + +-- | @multipart/form-data@ +instance Consumes UploadCookiesV1UploadCookiesPost MimeMultipartFormData + +-- | @application/json@ +instance Produces UploadCookiesV1UploadCookiesPost MimeJSON + diff --git a/lib/G4fClient/Client.hs b/lib/G4fClient/Client.hs new file mode 100644 index 0000000..0fed516 --- /dev/null +++ b/lib/G4fClient/Client.hs @@ -0,0 +1,223 @@ +{- + FastAPI + + No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + + OpenAPI Version: 3.1.0 + FastAPI API version: 0.1.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) +-} + +{-| +Module : G4fClient.Client +-} + +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE DeriveFunctor #-} +{-# LANGUAGE DeriveFoldable #-} +{-# LANGUAGE DeriveTraversable #-} +{-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-unused-imports #-} + +module G4fClient.Client where + +import G4fClient.Core +import G4fClient.Logging +import G4fClient.MimeTypes + +import qualified Control.Exception.Safe as E +import qualified Control.Monad.IO.Class as P +import qualified Control.Monad as P +import qualified Data.Aeson.Types as A +import qualified Data.ByteString as B +import qualified Data.ByteString.Char8 as BC +import qualified Data.ByteString.Lazy as BL +import qualified Data.ByteString.Lazy.Char8 as BCL +import qualified Data.Proxy as P (Proxy(..)) +import qualified Data.Text as T +import qualified Data.Text.Encoding as T +import qualified Network.HTTP.Client as NH +import qualified Network.HTTP.Client.MultipartFormData as NH +import qualified Network.HTTP.Types as NH +import qualified Web.FormUrlEncoded as WH +import qualified Web.HttpApiData as WH + +import Data.Function ((&)) +import Data.Monoid ((<>)) +import Data.Text (Text) +import GHC.Exts (IsString(..)) + +-- * Dispatch + +-- ** Lbs + +-- | send a request returning the raw http response +dispatchLbs + :: (Produces req accept, MimeType contentType) + => NH.Manager -- ^ http-client Connection manager + -> G4fClientConfig -- ^ config + -> G4fClientRequest req contentType res accept -- ^ request + -> IO (NH.Response BCL.ByteString) -- ^ response +dispatchLbs manager config request = do + initReq <- _toInitRequest config request + dispatchInitUnsafe manager config initReq + +-- ** Mime + +-- | pair of decoded http body and http response +data MimeResult res = + MimeResult { mimeResult :: Either MimeError res -- ^ decoded http body + , mimeResultResponse :: NH.Response BCL.ByteString -- ^ http response + } + deriving (Show, Functor, Foldable, Traversable) + +-- | pair of unrender/parser error and http response +data MimeError = + MimeError { + mimeError :: String -- ^ unrender/parser error + , mimeErrorResponse :: NH.Response BCL.ByteString -- ^ http response + } deriving (Show) + +-- | send a request returning the 'MimeResult' +dispatchMime + :: forall req contentType res accept. (Produces req accept, MimeUnrender accept res, MimeType contentType) + => NH.Manager -- ^ http-client Connection manager + -> G4fClientConfig -- ^ config + -> G4fClientRequest req contentType res accept -- ^ request + -> IO (MimeResult res) -- ^ response +dispatchMime manager config request = do + httpResponse <- dispatchLbs manager config request + let statusCode = NH.statusCode . NH.responseStatus $ httpResponse + parsedResult <- + runConfigLogWithExceptions "Client" config $ + do if (statusCode >= 400 && statusCode < 600) + then do + let s = "error statusCode: " ++ show statusCode + _log "Client" levelError (T.pack s) + pure (Left (MimeError s httpResponse)) + else case mimeUnrender (P.Proxy :: P.Proxy accept) (NH.responseBody httpResponse) of + Left s -> do + _log "Client" levelError (T.pack s) + pure (Left (MimeError s httpResponse)) + Right r -> pure (Right r) + return (MimeResult parsedResult httpResponse) + +-- | like 'dispatchMime', but only returns the decoded http body +dispatchMime' + :: (Produces req accept, MimeUnrender accept res, MimeType contentType) + => NH.Manager -- ^ http-client Connection manager + -> G4fClientConfig -- ^ config + -> G4fClientRequest req contentType res accept -- ^ request + -> IO (Either MimeError res) -- ^ response +dispatchMime' manager config request = do + MimeResult parsedResult _ <- dispatchMime manager config request + return parsedResult + +-- ** Unsafe + +-- | like 'dispatchReqLbs', but does not validate the operation is a 'Producer' of the "accept" 'MimeType'. (Useful if the server's response is undocumented) +dispatchLbsUnsafe + :: (MimeType accept, MimeType contentType) + => NH.Manager -- ^ http-client Connection manager + -> G4fClientConfig -- ^ config + -> G4fClientRequest req contentType res accept -- ^ request + -> IO (NH.Response BCL.ByteString) -- ^ response +dispatchLbsUnsafe manager config request = do + initReq <- _toInitRequest config request + dispatchInitUnsafe manager config initReq + +-- | dispatch an InitRequest +dispatchInitUnsafe + :: NH.Manager -- ^ http-client Connection manager + -> G4fClientConfig -- ^ config + -> InitRequest req contentType res accept -- ^ init request + -> IO (NH.Response BCL.ByteString) -- ^ response +dispatchInitUnsafe manager config (InitRequest req) = do + runConfigLogWithExceptions src config $ + do _log src levelInfo requestLogMsg + _log src levelDebug requestDbgLogMsg + res <- P.liftIO $ NH.httpLbs req manager + _log src levelInfo (responseLogMsg res) + _log src levelDebug ((T.pack . show) res) + return res + where + src = "Client" + endpoint = + T.pack $ + BC.unpack $ + NH.method req <> " " <> NH.host req <> NH.path req <> NH.queryString req + requestLogMsg = "REQ:" <> endpoint + requestDbgLogMsg = + "Headers=" <> (T.pack . show) (NH.requestHeaders req) <> " Body=" <> + (case NH.requestBody req of + NH.RequestBodyLBS xs -> T.decodeUtf8 (BL.toStrict xs) + _ -> "") + responseStatusCode = (T.pack . show) . NH.statusCode . NH.responseStatus + responseLogMsg res = + "RES:statusCode=" <> responseStatusCode res <> " (" <> endpoint <> ")" + +-- * InitRequest + +-- | wraps an http-client 'Request' with request/response type parameters +newtype InitRequest req contentType res accept = InitRequest + { unInitRequest :: NH.Request + } deriving (Show) + +-- | Build an http-client 'Request' record from the supplied config and request +_toInitRequest + :: (MimeType accept, MimeType contentType) + => G4fClientConfig -- ^ config + -> G4fClientRequest req contentType res accept -- ^ request + -> IO (InitRequest req contentType res accept) -- ^ initialized request +_toInitRequest config req0 = + runConfigLogWithExceptions "Client" config $ do + parsedReq <- P.liftIO $ NH.parseRequest $ BCL.unpack $ BCL.append (configHost config) (BCL.concat (rUrlPath req0)) + req1 <- P.liftIO $ _applyAuthMethods req0 config + P.when + (configValidateAuthMethods config && (not . null . rAuthTypes) req1) + (E.throw $ AuthMethodException $ "AuthMethod not configured: " <> (show . head . rAuthTypes) req1) + let req2 = req1 & _setContentTypeHeader & _setAcceptHeader + params = rParams req2 + reqHeaders = ("User-Agent", WH.toHeader (configUserAgent config)) : paramsHeaders params + reqQuery = let query = paramsQuery params + queryExtraUnreserved = configQueryExtraUnreserved config + in if B.null queryExtraUnreserved + then NH.renderQuery True query + else NH.renderQueryPartialEscape True (toPartialEscapeQuery queryExtraUnreserved query) + pReq = parsedReq { NH.method = rMethod req2 + , NH.requestHeaders = reqHeaders + , NH.queryString = reqQuery + } + outReq <- case paramsBody params of + ParamBodyNone -> pure (pReq { NH.requestBody = mempty }) + ParamBodyB bs -> pure (pReq { NH.requestBody = NH.RequestBodyBS bs }) + ParamBodyBL bl -> pure (pReq { NH.requestBody = NH.RequestBodyLBS bl }) + ParamBodyFormUrlEncoded form -> pure (pReq { NH.requestBody = NH.RequestBodyLBS (WH.urlEncodeForm form) }) + ParamBodyMultipartFormData parts -> NH.formDataBody parts pReq + + pure (InitRequest outReq) + +-- | modify the underlying Request +modifyInitRequest :: InitRequest req contentType res accept -> (NH.Request -> NH.Request) -> InitRequest req contentType res accept +modifyInitRequest (InitRequest req) f = InitRequest (f req) + +-- | modify the underlying Request (monadic) +modifyInitRequestM :: Monad m => InitRequest req contentType res accept -> (NH.Request -> m NH.Request) -> m (InitRequest req contentType res accept) +modifyInitRequestM (InitRequest req) f = fmap InitRequest (f req) + +-- ** Logging + +-- | Run a block using the configured logger instance +runConfigLog + :: P.MonadIO m + => G4fClientConfig -> LogExec m a +runConfigLog config = configLogExecWithContext config (configLogContext config) + +-- | Run a block using the configured logger instance (logs exceptions) +runConfigLogWithExceptions + :: (E.MonadCatch m, P.MonadIO m) + => T.Text -> G4fClientConfig -> LogExec m a +runConfigLogWithExceptions src config = runConfigLog config . logExceptions src diff --git a/lib/G4fClient/Core.hs b/lib/G4fClient/Core.hs new file mode 100644 index 0000000..72756be --- /dev/null +++ b/lib/G4fClient/Core.hs @@ -0,0 +1,589 @@ +{- + FastAPI + + No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + + OpenAPI Version: 3.1.0 + FastAPI API version: 0.1.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) +-} + +{-| +Module : G4fClient.Core +-} + +{-# LANGUAGE DeriveDataTypeable #-} +{-# LANGUAGE ExistentialQuantification #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TupleSections #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE CPP #-} +{-# OPTIONS_GHC -fno-warn-name-shadowing -fno-warn-unused-binds -fno-warn-unused-imports #-} + +module G4fClient.Core where + +import G4fClient.MimeTypes +import G4fClient.Logging + +import qualified Control.Arrow as P (left) +import qualified Control.DeepSeq as NF +import qualified Control.Exception.Safe as E +import qualified Data.Aeson as A +import qualified Data.ByteString as B +import qualified Data.ByteString.Base64.Lazy as BL64 +import qualified Data.ByteString.Builder as BB +import qualified Data.ByteString.Char8 as BC +import qualified Data.ByteString.Lazy as BL +import qualified Data.ByteString.Lazy.Char8 as BCL +import qualified Data.CaseInsensitive as CI +import qualified Data.Data as P (Data, Typeable, TypeRep, typeRep) +import qualified Data.Foldable as P +import qualified Data.Ix as P +import qualified Data.Kind as K (Type) +import qualified Data.Maybe as P +import qualified Data.Proxy as P (Proxy(..)) +import qualified Data.Text as T +import qualified Data.Text.Encoding as T +import qualified Data.Text.Lazy.Encoding as TL +import qualified Data.Time as TI +import qualified Data.Time.ISO8601 as TI +import qualified GHC.Base as P (Alternative) +import qualified Lens.Micro as L +import qualified Network.HTTP.Client.MultipartFormData as NH +import qualified Network.HTTP.Types as NH +import qualified Prelude as P +import qualified Text.Printf as T +import qualified Web.FormUrlEncoded as WH +import qualified Web.HttpApiData as WH + +import Control.Applicative ((<|>)) +import Control.Applicative (Alternative) +import Control.Monad.Fail (MonadFail) +import Data.Function ((&)) +import Data.Foldable(foldlM) +import Data.Monoid ((<>)) +import Data.Text (Text) +import Prelude (($), (.), (&&), (<$>), (<*>), Maybe(..), Bool(..), Char, String, fmap, mempty, pure, return, show, IO, Monad, Functor, maybe) + +-- * G4fClientConfig + +-- | +data G4fClientConfig = G4fClientConfig + { configHost :: BCL.ByteString -- ^ host supplied in the Request + , configUserAgent :: Text -- ^ user-agent supplied in the Request + , configLogExecWithContext :: LogExecWithContext -- ^ Run a block using a Logger instance + , configLogContext :: LogContext -- ^ Configures the logger + , configAuthMethods :: [AnyAuthMethod] -- ^ List of configured auth methods + , configValidateAuthMethods :: Bool -- ^ throw exceptions if auth methods are not configured + , configQueryExtraUnreserved :: B.ByteString -- ^ Configures additional querystring characters which must not be URI encoded, e.g. '+' or ':' + } + +-- | display the config +instance P.Show G4fClientConfig where + show c = + T.printf + "{ configHost = %v, configUserAgent = %v, ..}" + (show (configHost c)) + (show (configUserAgent c)) + +-- | constructs a default G4fClientConfig +-- +-- configHost: +-- +-- @http://localhost@ +-- +-- configUserAgent: +-- +-- @"g4f-client/7.1.4"@ +-- +newConfig :: IO G4fClientConfig +newConfig = do + logCxt <- initLogContext + return $ G4fClientConfig + { configHost = "http://localhost" + , configUserAgent = "g4f-client/7.1.4" + , configLogExecWithContext = runDefaultLogExecWithContext + , configLogContext = logCxt + , configAuthMethods = [] + , configValidateAuthMethods = True + , configQueryExtraUnreserved = "" + } + +-- | updates config use AuthMethod on matching requests +addAuthMethod :: AuthMethod auth => G4fClientConfig -> auth -> G4fClientConfig +addAuthMethod config@G4fClientConfig {configAuthMethods = as} a = + config { configAuthMethods = AnyAuthMethod a : as} + +-- | updates the config to use stdout logging +withStdoutLogging :: G4fClientConfig -> IO G4fClientConfig +withStdoutLogging p = do + logCxt <- stdoutLoggingContext (configLogContext p) + return $ p { configLogExecWithContext = stdoutLoggingExec, configLogContext = logCxt } + +-- | updates the config to use stderr logging +withStderrLogging :: G4fClientConfig -> IO G4fClientConfig +withStderrLogging p = do + logCxt <- stderrLoggingContext (configLogContext p) + return $ p { configLogExecWithContext = stderrLoggingExec, configLogContext = logCxt } + +-- | updates the config to disable logging +withNoLogging :: G4fClientConfig -> G4fClientConfig +withNoLogging p = p { configLogExecWithContext = runNullLogExec} + +-- * G4fClientRequest + +-- | Represents a request. +-- +-- Type Variables: +-- +-- * req - request operation +-- * contentType - 'MimeType' associated with request body +-- * res - response model +-- * accept - 'MimeType' associated with response body +data G4fClientRequest req contentType res accept = G4fClientRequest + { rMethod :: NH.Method -- ^ Method of G4fClientRequest + , rUrlPath :: [BCL.ByteString] -- ^ Endpoint of G4fClientRequest + , rParams :: Params -- ^ params of G4fClientRequest + , rAuthTypes :: [P.TypeRep] -- ^ types of auth methods + } + deriving (P.Show) + +-- | 'rMethod' Lens +rMethodL :: Lens_' (G4fClientRequest req contentType res accept) NH.Method +rMethodL f G4fClientRequest{..} = (\rMethod -> G4fClientRequest { rMethod, ..} ) <$> f rMethod +{-# INLINE rMethodL #-} + +-- | 'rUrlPath' Lens +rUrlPathL :: Lens_' (G4fClientRequest req contentType res accept) [BCL.ByteString] +rUrlPathL f G4fClientRequest{..} = (\rUrlPath -> G4fClientRequest { rUrlPath, ..} ) <$> f rUrlPath +{-# INLINE rUrlPathL #-} + +-- | 'rParams' Lens +rParamsL :: Lens_' (G4fClientRequest req contentType res accept) Params +rParamsL f G4fClientRequest{..} = (\rParams -> G4fClientRequest { rParams, ..} ) <$> f rParams +{-# INLINE rParamsL #-} + +-- | 'rParams' Lens +rAuthTypesL :: Lens_' (G4fClientRequest req contentType res accept) [P.TypeRep] +rAuthTypesL f G4fClientRequest{..} = (\rAuthTypes -> G4fClientRequest { rAuthTypes, ..} ) <$> f rAuthTypes +{-# INLINE rAuthTypesL #-} + +-- * HasBodyParam + +-- | Designates the body parameter of a request +class HasBodyParam req param where + setBodyParam :: forall contentType res accept. (Consumes req contentType, MimeRender contentType param) => G4fClientRequest req contentType res accept -> param -> G4fClientRequest re