- Refactor RunPod client to use a new GraphQL builder. - This improves the readability and maintainability of the code. - The old `build_query` function was removed, and the new - `QueryBuilder` struct is now used. This allows for a more - flexible and extensible approach to constructing GraphQL - queries. The example in `runpod_example.vsh` is now - commented out until the new GraphQL builder is fully - implemented. Co-authored-by: mariobassem12 <mariobassem12@gmail.com>
201 lines
4.8 KiB
V
201 lines
4.8 KiB
V
module runpod
|
|
|
|
import freeflowuniverse.herolib.core.httpconnection
|
|
import json
|
|
|
|
// Represents the main structure for interacting with the RunPod API.
|
|
// Provides utilities to manage HTTP connections and perform GraphQL queries.
|
|
fn (mut rp RunPod) httpclient() !&httpconnection.HTTPConnection {
|
|
mut http_conn := httpconnection.new(
|
|
name: 'runpod_vclient_${rp.name}'
|
|
url: rp.base_url
|
|
cache: true
|
|
retry: 3
|
|
)!
|
|
http_conn.default_header.add(.authorization, 'Bearer ${rp.api_key}')
|
|
return http_conn
|
|
}
|
|
|
|
// Retrieves the field name from the `FieldData` struct, either from its attributes or its name.
|
|
fn get_field_name(field FieldData) string {
|
|
mut field_name := ''
|
|
if field.attrs.len > 0 {
|
|
for attr in field.attrs {
|
|
attrs := attr.trim_space().split(':')
|
|
if attrs.len == 2 && attrs[0] == 'json' {
|
|
field_name = attrs[1].trim_space()
|
|
continue
|
|
}
|
|
}
|
|
} else {
|
|
field_name = field.name
|
|
}
|
|
return field_name
|
|
}
|
|
|
|
// // Constructs JSON-like request fields from a struct.
|
|
// fn get_request_fields[T](struct_ T) string {
|
|
// mut body_ := '{ '
|
|
// mut fields := []string{}
|
|
|
|
// $for field in T.fields {
|
|
// mut string_ := ''
|
|
// omit := 'omitempty' in field.attrs
|
|
// mut empty_string := false
|
|
// $if field.typ is string {
|
|
// empty_string = struct_.$(field.name) == ''
|
|
// }
|
|
// if !omit || !empty_string {
|
|
// string_ += get_field_name(field)
|
|
// string_ += ': '
|
|
|
|
// $if field.is_enum {
|
|
// string_ += struct_.$(field.name).to_string()
|
|
// } $else $if field.typ is string {
|
|
// item := struct_.$(field.name)
|
|
// string_ += "\"${item}\""
|
|
// } $else $if field.is_array {
|
|
// string_ += '['
|
|
// for i in struct_.$(field.name) {
|
|
// string_ += get_request_fields(i)
|
|
// }
|
|
// string_ += ']'
|
|
// } $else $if field.is_struct {
|
|
// string_ += get_request_fields(struct_.$(field.name))
|
|
// } $else {
|
|
// item := struct_.$(field.name)
|
|
// string_ += '${item}'
|
|
// }
|
|
|
|
// fields << string_
|
|
// }
|
|
// }
|
|
// body_ += fields.join(', ')
|
|
// body_ += ' }'
|
|
// return body_
|
|
// }
|
|
|
|
// // Constructs JSON-like response fields for a given struct.
|
|
// fn get_response_fields[R](struct_ R) string {
|
|
// mut body_ := '{ '
|
|
|
|
// $for field in R.fields {
|
|
// $if field.is_struct {
|
|
// // Recursively process nested structs
|
|
// body_ += '${field.name} '
|
|
// body_ += get_response_fields(struct_.$(field.name))
|
|
// } $else {
|
|
// body_ += get_field_name(field)
|
|
// body_ += ' '
|
|
// }
|
|
// }
|
|
// body_ += ' }'
|
|
// return body_
|
|
// }
|
|
|
|
// // Enum representing the type of GraphQL operation.
|
|
// pub enum QueryType {
|
|
// query
|
|
// mutation
|
|
// }
|
|
|
|
// // Struct for building GraphQL queries with request and response models.
|
|
// @[params]
|
|
// pub struct BuildQueryArgs[T, R] {
|
|
// pub:
|
|
// query_type QueryType // query or mutation
|
|
// method_name string
|
|
// request_model T @[required]
|
|
// response_model R @[required]
|
|
// }
|
|
|
|
// // Builds a GraphQL query or mutation string from provided arguments.
|
|
// fn build_query[T, R](args BuildQueryArgs[T, R]) string {
|
|
// mut request_fields := T{}
|
|
// mut response_fields := R{}
|
|
|
|
// if args.request_model {
|
|
// request_fields = get_request_fields(args.request_model)
|
|
// }
|
|
|
|
// if args.response_model {
|
|
// response_fields = get_response_fields(args.response_model)
|
|
// }
|
|
|
|
// mut query := ''
|
|
|
|
// if args.request_model && args.response_model{
|
|
// query := '${args.query_type.to_string()} { ${args.method_name}(input: ${request_fields}) ${response_fields} }'
|
|
// }
|
|
|
|
// if args.response_model && !args.request_model{
|
|
// query := '${args.query_type.to_string()} { ${response_fields} }'
|
|
// }
|
|
|
|
// // Wrap in the final structure
|
|
// gql := GqlQuery{
|
|
// query: query
|
|
// }
|
|
|
|
// // Return the final GraphQL query as a JSON string
|
|
// return json.encode(gql)
|
|
// }
|
|
|
|
// Converts the `QueryType` enum to its string representation.
|
|
fn (op OperationType) to_string() string {
|
|
return match op {
|
|
.query {
|
|
'query'
|
|
}
|
|
.mutation {
|
|
'mutation'
|
|
}
|
|
}
|
|
}
|
|
|
|
// Enum representing HTTP methods.
|
|
enum HTTPMethod {
|
|
get
|
|
post
|
|
put
|
|
delete
|
|
}
|
|
|
|
// Sends an HTTP request to the RunPod API with the specified method, path, and data.
|
|
fn (mut rp RunPod) make_request[T](method HTTPMethod, path string, data string) !T {
|
|
mut request := httpconnection.Request{
|
|
prefix: path
|
|
data: data
|
|
debug: true
|
|
dataformat: .json
|
|
}
|
|
|
|
mut http := rp.httpclient()!
|
|
mut response := T{}
|
|
|
|
match method {
|
|
.get {
|
|
request.method = .get
|
|
response = http.get_json_generic[T](request)!
|
|
}
|
|
.post {
|
|
request.method = .post
|
|
response = http.post_json_generic[T](request)!
|
|
}
|
|
.put {
|
|
request.method = .put
|
|
response = http.put_json_generic[T](request)!
|
|
}
|
|
.delete {
|
|
request.method = .delete
|
|
response = http.delete_json_generic[T](request)!
|
|
}
|
|
}
|
|
|
|
if response.errors.len > 0 {
|
|
return error('Error while sending the request due to: ${response.errors[0]['message']}')
|
|
}
|
|
|
|
return response
|
|
}
|