racket-rash icon indicating copy to clipboard operation
racket-rash copied to clipboard

Rash in Jupyter (with iracket)

Open ixemad opened this issue 3 years ago • 5 comments

First of all, congratulations for this beautiful piece of code.

Recently, I have been using it in my daily work with Emacs + Org-mode to create "literate scripts". I would also like to propose my colleagues to use it but they feel Emacs as a real obstacle. They are more receptive to Jupyter, though.

So, trying to connect the dots, I found a Racket kernel for Jupyter (iRacket). However, I have not been able to create Jupyter cells that make use of the Rash reader on it. Would it be possible?

ixemad avatar Jun 26 '22 19:06 ixemad

On Sun, Jun 26, 2022 at 12:21:34PM -0700, ixemad wrote:

First of all, congratulations for this beautiful piece of code.

Thanks! I'm glad you like it.

Recently, I have been using it in my daily work with Emacs + Org-mode to create "literate scripts".

Do you have any example of this you can share? I'd be interested to see what you are doing.

I would also like to propose my colleagues to use it but they feel Emacs as a real obstacle. They are more receptive to Jupyter, though.

So, trying to connect the dots, I found a Racket kernel for Jupyter (iRacket). However, I have not been able to create Jupyter cells that make use of the Rash reader on it. Would it be possible?

I haven't used it, but it looks like it should be. The iRacket documentation has a section about using it with other languages and readers. Note that there is an optional #:reader argument. Rash's reader is called Linea. My documentation on Linea isn't, uh, superb. But you should be able to get it working if you use #:reader linea/reader (or maybe just #:reader linea, but without looking closer I'm pretty sure it's the former).

I hope that helps, despite being delayed and shallow help. Good luck, Rash with Jupyter sounds awesome!

willghatch avatar Jul 08 '22 20:07 willghatch

Yeah, I tried to use linea both ways but it did not work. I get the following error in the Jupyter's backend if I set the reader to linea/reader:

open-input-file: cannot open module file
  module path: linea/reader
  path: /home/user/.local/share/racket/8.5/pkgs/linea/reader.rkt
  system error: no such file or directory; rkt_err=3
  context...:
   /home/user/.local/share/racket/8.5/pkgs/iracket/lang.rkt:65:2: config:get-read-syntax
   /home/user/.local/share/racket/8.5/pkgs/iracket/private/kernel.rkt:124:13

Oh the other hand, there is no iRacket complaint if I just set linea as the reader. However, it fails to execute any Rash cell.

imagen

Of course, I tested that iRacket was correctly installed in my machine.

imagen

ixemad avatar Jul 09 '22 07:07 ixemad

With respect to the (amazing) Org-mode example, the next one is likely not the clearest one but it will allow me to expose how flexible (and powerful) is the combination of Org-mode + Rash (+ Qi):

#+name: vulnerable_lambda/lambda-arn
#+header: :var assumed-role=vulnerable_lambda/assumed-role
#+header: :var regions=ALL-REGIONS
#+begin_src racket :lang rash
  (require racket/function
           racket/string
           racket/stream
           json
           qi )

  (define (/ entry-name)
    (☯ (~> (hash-ref entry-name) (if list? sep _))))

  (define (@ entry-name op entry-value)
    (☯ (pass (esc (λ (key) (op (hash-ref key entry-name) entry-value))))) )

  (void (putenv "AWS_ACCESS_KEY_ID"     #{ echo $assumed-role | jq -r ".Credentials.AccessKeyId" }))
  (void (putenv "AWS_SECRET_ACCESS_KEY" #{ echo $assumed-role | jq -r ".Credentials.SecretAccessKey" }))
  (void (putenv "AWS_SESSION_TOKEN"     #{ echo $assumed-role | jq -r ".Credentials.SessionToken" }))

  (let ([lambdas
         (for*/stream ([region (string-split regions)]
                       [result (in-list
                                (with-handlers ([exn:fail? (const '())])
                                  #{ aws lambda list-functions \
                                         --region $region \
                                         |>> string->jsexpr \
                                         |> (☯ (~> (/ 'Functions)
                                                   (>< (/ 'FunctionArn))
                                                   ▽)) } ) ) ] )
           result) ])
    (if (stream-empty? lambdas)
        "no lambdas in any region"
        (~> (lambdas) stream-first display) ) )
#+end_src
#+RESULTS[087d42e5287904de8dadb0f07a8eae4e90888f72]: vulnerable_lambda/lambda-arn
: arn:aws:lambda:us-east-1:7245XXXX8614:function:vulnerable_lambda_cgidb34c8zbk3d-policy_applier_lambda1

So, the Org-mode block vulnerable_lambda/lambda-arn is using as input parameters (assumed-role, regions) the output of other two previous blocks (vulnerable_lambda/assumed-role and ALL-REGIONS). This block combines Racket, Rash, Qi and jq to get as a cached result arn:aws:lambda:us-east-1:7245XXXX8614:function:vulnerable_lambda_cgidb34c8zbk3d-policy_applier_lambda1 which can be reused by another block. Beautiful, isn't it? :smile:

ixemad avatar Jul 09 '22 08:07 ixemad

I saw but didn't notice that iRacket code runs in a sandbox. A far as I can see, the sandbox refuses to run the following example code:

(require shell/pipeline)
(run-subprocess-pipeline '(echo))
subprocess: `execute' access denied for /usr/bin/echo
  context...:
   body of top-level
   /home/user/.local/share/racket/8.5/pkgs/shell-pipeline/private/subprocess-pipeline.rkt:663:0: run-pipeline-members
   /home/user/.local/share/racket/8.5/pkgs/shell-pipeline/private/subprocess-pipeline.rkt:510:0: run-pipeline/spec
   /home/user/.local/share/racket/8.5/pkgs/shell-pipeline/private/subprocess-pipeline.rkt:441:0: run-subprocess-pipeline
   /usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:555:3

So, my colleagues will have to love Emacs :smile:

ixemad avatar Jul 10 '22 18:07 ixemad

Alright, with respect to my previous comment, iRacket can be hacked to allow the execute permission in the sandbox (specifically, by modifying the sandbox-path-permissions parameter). Of course, this is a sensitive decision that must be weighed.

ixemad avatar Jul 11 '22 07:07 ixemad