k1lib.serve module

This module is for quickly serving Python functions in an interactive website, so that you can build interfaces for your experiments real quick. Let’s say you have a function in the file “a.py”:

def endpoint(a:int=3, b:float=4, c:bool=True) -> float:
   if c: return a + b
   else: return a * b

You want to be able to expose a nice interactive interface so that you can present to everyone, or to be used in other systems, then you can do something like this:

cbs = k1.Callbacks()
cbs.add(serve.FromPythonFile("a.py"))
cbs.add(serve.BuildPythonFile(port=5138))
cbs.add(serve.StartServer())
cbs.add(serve.GenerateHtml(htmlFile="index.html"))

serve.serve(cbs)

This will start up a local server at the specified port (this case 5138), and dumps a index.html file in the current folder. Opening it up will give you this interface:

_images/serve.png

That’s pretty much it. You can add in your own callbacks, to enable further integration with your systems. You can also customize the given callbacks more.

An example of all supported data types and interfaces:

def endpoint(a:int=3, b:float=5.2, c:str="short string", d:serve.text(True)="paragraph",
             e:bool=True, f:range(3, 21)=6, g:serve.slider(1, 2)=1.2,
             h:PIL.Image.Image=someImg, i:bytes=someBinaryData,
             j:["opt 1", "opt 2"]="opt 1") -> float:
   pass

And how they’re displayed:

  • int, float, str, serve.text(True): text box. Could be multiline for text case

  • bool: checkbox

  • range(3, 21): discrete slider

  • serve.slider(1, 2): continuous slider

  • PIL.Image.Image`: file upload. If return value is this then will just display the image directly

  • bytes: file upload

  • ["opt 1", "opt 2"]: dropdown menu

See a few demo examples at https://mlexps.com/ (at the very bottom of the page)

k1lib.serve.main.tag_serve(node: Optional[str] = None, condaEnv: Optional[str] = None, condaPath: str = '~/miniconda3')[source]

Tag that marks the cell that will be extracted to an independent file and executed. Example:

# serve(node="user@hostname", condaEnv="torch")

If a remote node is specified, internally, this will run commands on that node using ssh, so make sure it’s reachable via “ssh user@hostname” with default ssh identity, or else it wouldn’t work.

If .condaEnv is specified, then will activate conda before executing the script. The activation command will be “{condaPath}/bin/activate {condaEnv}”

Parameters
  • node – what node should the script be executed?

  • condaEnv – if specified, will activate that conda env before executing

class k1lib.serve.main.FromNotebook(fileName, tagName: str = 'serve', allTags: list[str] = ('test', 'notest', 'donttest', 'thumbnail', 'export', 'serve', 'noserve', 'dash'))[source]

Bases: Callback

__init__(fileName, tagName: str = 'serve', allTags: list[str] = ('test', 'notest', 'donttest', 'thumbnail', 'export', 'serve', 'noserve', 'dash'))[source]

Grabs source code from a Jupyter notebook. Will grab cells with the comment like # serve in the first line.

See tag_serve() to see more about its options

Parameters
  • fileName – notebook path

  • tagName – which tag to extract out?

  • allTags – all possible custom tags that you use. It might complain if there’s a tag in your notebook that it doesn’t know about, so add all of your commonly used tags here

fetchSource()[source]
class k1lib.serve.main.FromPythonFile(fileName)[source]

Bases: Callback

__init__(fileName)[source]

Grabs source code from a python file.

fetchSource()[source]
class k1lib.serve.main.BuildPythonFile(port=None)[source]

Bases: Callback

__init__(port=None)[source]

Builds the output Python file, ready to be served on localhost.

Parameters

port – which port to run on localhost. If not given, then a port will be picked at random, and will be available at cbs.l['port']

buildPythonFile()[source]
class k1lib.serve.main.BuildDashFile[source]

Bases: BuildPythonFile

__init__()[source]

Builds the output Python file for a Dash app, ready to be served on localhost

class k1lib.serve.main.StartServer(maxInitTime=10)[source]

Bases: Callback

__init__(maxInitTime=10)[source]

Starts the server, verify that it starts okay and dumps meta information (including function signatures) to cbs.l

Parameters

maxInitTime – time to wait in seconds until the server is online before declaring it’s unsuccessful

startServer()[source]
class k1lib.serve.main.GenerateHtml(serverPrefix=None, htmlFile=None, title='Interactive demo')[source]

Bases: Callback

__init__(serverPrefix=None, htmlFile=None, title='Interactive demo')[source]

Generates a html file that communicates with the server.

Parameters
  • serverPrefix – prefix of server for back and forth requests, like “https://example.com/proj1”. If empty, tries to grab cbs.l["serverPrefix"], which you can deposit from your own callback. If that’s not available then it will fallback to localhost:port

  • htmlFile – path of the target html file. If not specified then a temporary file will be created and made available in cbs.l["htmlFile"]

  • title – title of html page

generateHtml()[source]
k1lib.serve.main.commonCbs()[source]

Grabs common callbacks, including BuildPythonFile and StartServer

k1lib.serve.main.serve(cbs)[source]

Runs the serving pipeline.

class k1lib.serve.main.baseType[source]

Bases: object

__init__()[source]

Base type for all widget types

getConfig()[source]
class k1lib.serve.main.text(multiline: bool = True, password: bool = False)[source]

Bases: baseType

__init__(multiline: bool = True, password: bool = False)[source]

Represents text, either on single or multiple lines. If password is true, then will set multiline to false automatically, and creates a text box that blurs out the contents. Example:

def endpoint(s:serve.text()="abc") -> str: pass

For inputs only. Use str for outputs

class k1lib.serve.main.slider(start: float, stop: float, intervals: int = 100)[source]

Bases: baseType

__init__(start: float, stop: float, intervals: int = 100)[source]

Represents a slider from start to stop with a bunch of intervals in the middle. If defValue is not specified, uses the middle point between start and stop. Example:

def endpoint(a:serve.slider(2, 3.2)=2.3) -> str: pass

For inputs only

class k1lib.serve.main.html[source]

Bases: baseType

__init__()[source]

Raw html. Example:

def endpoint() -> serve.html(): pass

For outputs only

class k1lib.serve.main.json[source]

Bases: baseType

__init__()[source]

Raw json. Example:

def endpoint(a:serve.json()={"a": 3}) -> serve.json(): pass

For inputs and outputs

class k1lib.serve.main.date(min=None, max=None)[source]

Bases: baseType

__init__(min=None, max=None)[source]

Local date time (no timezone information). Example:

def endpoint(d:serve.date()="2023-12-07T00:00:00") -> str: pass
Parameters

min – min date, also in format ‘2023-12-07T00:00:00’

class k1lib.serve.main.serialized[source]

Bases: baseType

__init__()[source]

For serialized objects using dill. Example:

def endpoint(a:serve.serialized()) -> serve.serialized():
    return {"any": "data structure", "you": "want", "even": np.random.randn(100)}
class k1lib.serve.main.apiKey(apiKey=<class 'str'>)[source]

Bases: baseType

__init__(apiKey=<class 'str'>)[source]

Protects your endpoint with an api key. Example:

def endpoint(apiKey:serve.apiKey("your api key here")="") -> str: pass

When compiled, your api key won’t appear anywhere, not in the html, not in the meta files, and someone calling the endpoint must specify it, else it will just errors out

k1lib.serve.main.analyze(f)[source]
k1lib.serve.main.webToPy(o, klass: baseType)[source]
k1lib.serve.main.pyToWeb(o, klass: baseType)[source]