#Hi @Helder Correia @Jeremy Adams
1 messages · Page 1 of 1 (latest)
@mystic isle
chatGPT suggested this change
@object_type
class Infisical:
infisical_client: InfisicalSDKClient = dataclasses.field(init=False)
api_url: Annotated[
dataclasses.InitVar[str],
Doc("Your self-hosted Infisical site URL. Default: https://app.infisical.com."),
] = "https://app.infisical.com"
def __post_init__(self, api_url: str = "https://app.infisical.com"):
self.infisical_client = InfisicalSDKClient(host=api_url)
essentially giving an explicit default value for api_url in __post_init__
After making the change above, I get this error now:
✔ connect 0.9s
✔ initialize 1.2s
✔ prepare 0.0s
✔ setSecret(name: "92e708236d9a1b2ae8034b01a24880af4ccf51cb267db82643242e8665af890f"): Secret! 0.0s
✔ setSecret(name: "2713da821216077d2478edd14d5330d08bb6fb63371a2b452d565024e9cb5c06"): Secret! 0.0s
✘ infisical(apiUrl: "https://app.infisical.com"): Infisical! 2.2s
! call constructor: process "/runtime" did not complete successfully: exit code: 1
┃ ╭─ Error ──────────────────────────────────────────────────────────────────────╮
┃ │ Failed to serialize result: Object of type InfisicalSDKClient is not JSON │
┃ │ serializable │
┃ ╰──────────────────────────────────────────────────────────────────────────────╯
Error: response from query: input: infisical resolve: call constructor: process "/runtime" did not complete successfully: exit code: 1
Stderr:
╭─ Error ──────────────────────────────────────────────────────────────────────╮
│ Failed to serialize result: Object of type InfisicalSDKClient is not JSON │
│ serializable │
╰──────────────────────────────────────────────────────────────────────────────╯
@function
def get_secret_by_name(
...
) -> dagger.Secret:
"""Get a secret by name"""
secret = self.infisical_client.secrets.get_secret_by_name(
secret_name=secret_name,
project_id=project_id,
environment_slug=environment_slug,
secret_path=secret_path,
expand_secret_references=expand_secret_references,
include_imports=include_imports,
)
return dag.set_secret(secret_name, secret.secret.secret_value)
seems to be an issue with the infisical_client #1280272916478689310 message
@lusty plover So does the private method instance also has to serializable, or does have some condition as like the arguments like only dagger or primitives methods?
The error is from InfisicalClient on method instance?
@lusty plover Also I think the default URL is not a good fix. The post init should had the value passed by dagger engine. The present one passed because even when not given its using default value. But I did pass in the argument of api_url as needed.
Each function in a chain runs in a separate container instance/run (different Python processes), and between those runs the object needs to be serialized and deserialized even on attributes that aren't exposed as Dagger Functions because they're still a part of the object's state. The Dagger engine needs to report to the next function in the chain what the current state of the object is so the next function initializes it before running its code. This also explains why you may see an issue only when chaining, because it's when that serialization/deserialization boundary is crossed.
@object_type is a wrapper around @dataclass, so the objects are serialized based on dataclasses.asdict. In this case, the InfisicalSDKClient object doesn't seem to be JSON serializable:
>>> import json
>>> from infisical_sdk import InfisicalSDKClient
>>> json.dumps(InfisicalSDKClient(host="https://app.infisical.com"))
TypeError: Object of type InfisicalSDKClient is not JSON serializable
That's ok though. It seems there's a few blindspots in the SDK that can be fixed, but may I suggest you do this instead:
@object_type
class Infisical:
api_url: Annotated[
str,
Doc("Your self-hosted Infisical site URL. Default: https://app.infisical.com."),
] = "https://app.infisical.com"
@cached_property
def infisical_client(self) -> InfisicalSDKClient:
return InfisicalSDKClient(host=self.api_url)
This way api_url is easily serialized although not exposed as a function, and self.infisical_client is ensured to be instantiated only once per Infisical instance, but without going through serialization.
@velvet wyvern thank you, yes I had issues even when I stripped things down quite a bit
import dataclasses
from typing import Annotated
import dagger
from dagger import Doc, dag, function, object_type
import infisical_sdk
from infisical_sdk import UniversalAuth, InfisicalSDKClient
@object_type
class Infisical:
api_url: Annotated[
dataclasses.InitVar[str],
Doc("Your self-hosted Infisical site URL. Default: https://app.infisical.com."),
] = "https://app.infisical.com"
client_id: Annotated[dagger.Secret, Doc("Your Machine Identity Client ID")]
client_secret: Annotated[dagger.Secret, Doc("Your Machine Identity Client Secret.")]
@function
def universal_auth(
self,
) -> str:
"""Authenticate with Universal Auth"""
# client_id_dagger_secret = await self.client_id.plaintext()
# client_secret_dagger_secret = await self.client_secret.plaintext()
infisical_client = InfisicalSDKClient(host=self.api_url)
auth = UniversalAuth(infisical_client)
tok = infisical_client.auth.universal_auth.login(
client_id='<id>', client_secret='<token>'
).to_dict().get(key='accessToken')
print(str(tok))
return str(tok)
@velvet wyvern Understood. I am learning a lot on dagger now. It would be great if the team can design a more focused doc sections for developers who are implementing plugins.
May be my inexperience in python could be the reason. But it would be really great to work on it for easier understanding of dagger properties. I felt it needs a bit more organized.
One last doubt is to do chaining with sdk exposed?
Can i do with chaining with @cache_property or I cannot do it at all unless the SDK itself is JSON serializable?
Update @velvet wyvern Yes the @cached_property did the trick. Need to now check python doc on how to handle the singleton pattern, where we set the token internally.
Can't chain with @cached_property. That's for internal use (i.e., Python process instead of Dagger API).
In this example, you'd need to remove the dataclasses.InitVar wrapper because it'll make it an init-only argument (constructor) and thus not available as an instance attribute at self.api_url. For more on this: https://docs.python.org/3/library/dataclasses.html#init-only-variables