2021-12-15 06:35:32 -08:00
import os
2021-12-06 12:43:34 -08:00
import ssl
2023-05-04 00:58:06 -07:00
from typing import Dict , Optional , Union
2021-12-06 12:43:34 -08:00
import attr
2024-10-25 13:20:33 -07:00
DEFAULT_BASE_URL = " https://api.zoo.dev "
2021-12-06 12:43:34 -08:00
@attr.s ( auto_attribs = True )
class Client :
2023-05-04 00:58:06 -07:00
""" A Client which has been authenticated for use on secured endpoints of the KittyCAD API. """ # noqa: E501
2021-12-06 12:43:34 -08:00
2022-02-27 18:39:04 -08:00
token : str = attr . ib ( kw_only = True )
2024-10-25 13:20:33 -07:00
base_url : str = attr . ib ( default = DEFAULT_BASE_URL )
2021-12-06 12:43:34 -08:00
cookies : Dict [ str , str ] = attr . ib ( factory = dict , kw_only = True )
headers : Dict [ str , str ] = attr . ib ( factory = dict , kw_only = True )
2023-12-21 09:28:32 -08:00
timeout : float = attr . ib ( 120.0 , kw_only = True )
2021-12-06 12:43:34 -08:00
verify_ssl : Union [ str , bool , ssl . SSLContext ] = attr . ib ( True , kw_only = True )
def get_headers ( self ) - > Dict [ str , str ] :
""" Get headers to be used in all endpoints """
2022-02-27 18:39:04 -08:00
return { " Authorization " : f " Bearer { self . token } " , * * self . headers }
2021-12-06 12:43:34 -08:00
def with_headers ( self , headers : Dict [ str , str ] ) - > " Client " :
""" Get a new client matching this one with additional headers """
return attr . evolve ( self , headers = { * * self . headers , * * headers } )
def get_cookies ( self ) - > Dict [ str , str ] :
return { * * self . cookies }
def with_cookies ( self , cookies : Dict [ str , str ] ) - > " Client " :
""" Get a new client matching this one with additional cookies """
return attr . evolve ( self , cookies = { * * self . cookies , * * cookies } )
def get_timeout ( self ) - > float :
return self . timeout
def with_timeout ( self , timeout : float ) - > " Client " :
""" Get a new client matching this one with a new timeout (in seconds) """
return attr . evolve ( self , timeout = timeout )
2023-11-28 16:37:47 -08:00
def with_base_url ( self , url : str ) - > " Client " :
""" Get a new client matching this one with a new base url """
return attr . evolve ( self , base_url = url )
2021-12-06 12:43:34 -08:00
@attr.s ( auto_attribs = True )
2022-02-27 18:39:04 -08:00
class ClientFromEnv ( Client ) :
2024-10-25 13:20:33 -07:00
""" A Client which has been authenticated for use on secured endpoints that uses the KITTYCAD_API_TOKEN or ZOO_API_TOKEN environment variable for the authentication token.
Optionally , you can use ` ZOO_HOST ` to set the base url .
This implies you are hosting your own instance of the KittyCAD API .
""" # noqa: E501
2023-05-04 00:58:06 -07:00
token : str = attr . field ( )
2024-10-25 13:20:33 -07:00
base_url : str = attr . ib ( default = os . getenv ( " ZOO_HOST " , DEFAULT_BASE_URL ) )
2023-05-04 00:58:06 -07:00
@token.default
def set_token ( self ) :
maybe_token : Optional [ str ] = os . getenv ( " KITTYCAD_API_TOKEN " )
if maybe_token is None :
2024-10-25 13:20:33 -07:00
# Try the ZOO_API_TOKEN environment variable
maybe_token = os . getenv ( " ZOO_API_TOKEN " )
if maybe_token is None :
raise ValueError (
" KITTYCAD_API_TOKEN or ZOO_API_TOKEN environment variable must be set to use ClientFromEnv "
)
2023-05-04 00:58:06 -07:00
token : str = maybe_token
2024-10-25 13:20:33 -07:00
2023-05-04 00:58:06 -07:00
return token
2021-12-15 06:32:32 -08:00
def get_headers ( self ) - > Dict [ str , str ] :
""" Get headers to be used in authenticated endpoints """
return { " Authorization " : f " Bearer { self . token } " , * * self . headers }