Facebook
From solid_fuel, 4 Months ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 71
  1. # Untitled notebook
  2.  
  3. ```elixir
  4. # This is the notebook configuration, for a production app you would handle this with mix.exs
  5. #   and the various config files to build a packaged release with the appropriate configurations baked in
  6. Mix.install([
  7.   {:pythonx, "~> 0.4.0"},
  8.   {:req, "~> 0.5.8"},
  9.   {:flame, "~> 0.5.2"}
  10. ], config: [
  11.   flame: [
  12.     backend: FLAME.LocalBackend
  13.   ],
  14.   pythonx: [
  15.     uv_init: [
  16.       pyproject_toml:
  17.         """
  18.         [project]
  19.         name = "project"
  20.         version = "0.0.0"
  21.         requires-python = "==3.13.*"
  22.         dependencies = [
  23.           "pytesseract==0.3.13",
  24.           "pillow==11.1.0"
  25.         ]
  26.         """
  27.     ]
  28.   ]
  29. ])
  30. ```
  31.  
  32. ## Section
  33.  
  34. ```elixir
  35. # Configure the Flame Pool on the calling node
  36. # Normally you do this on application startup
  37. # Note that startup needs to be handled slightly differently
  38. #   on FLAME worker nodes, see the flame docs for details
  39. children = [
  40.   {FLAME.Pool,
  41.    name: Demo.FlameRunner,
  42.    min: 0,
  43.    max: 10,
  44.    max_concurrency: 5,
  45.    idle_shutdown_after: 30_000},
  46. ]
  47.  
  48. opts = [strategy: :one_for_one, name: Demo.Supervisor]
  49. Supervisor.start_link(children, opts)
  50. ```
  51.  
  52. ```elixir
  53. # Load the image from unsplash
  54. # Note that the image is loaded here on the calling node
  55.  
  56. url = "https://unsplash.com/photos/95t94hZTESw/download?ixid=M3wxMjA3fDB8MXxhbGx8fHx8fHx8fHwxNzQwMDYwMjg4fA&force=true&w=640"
  57. binary = Req.get!(url).body
  58. ```
  59.  
  60. ```elixir
  61. # Calling process - this runs on whatever node wants to start the task,
  62. #   and will block until the call finishes executing on the Flame node (or times out)
  63.  
  64. {:ok, result} =
  65.   FLAME.call(Demo.FlameRunner, fn ->  
  66.     # Flame Process - this is executed on a FLAME Runner Node, started on the configured backend
  67.     {result, _globals} =
  68.       Pythonx.eval(
  69.         """
  70.         import pytesseract
  71.         import io
  72.         import PIL
  73.  
  74.         # This is a fix for an issue on the machines I am using -
  75.         #  python was having trouble finding tesseract, which is installed globally
  76.         pytesseract.pytesseract.tesseract_cmd = r'/usr/local/bin/tesseract'
  77.        
  78.         image = PIL.Image.open(io.BytesIO(binary))
  79.         pytesseract.image_to_string(image)
  80.         """,
  81.         %{"binary" => binary}
  82.       )
  83.  
  84.     decoded_result = Pythonx.decode(result)
  85.    
  86.     {:ok, decoded_result}
  87.   end)
  88.  
  89. # Back on the calling node
  90. IO.puts result
  91. ```
  92.