on master help sign in
fixes to examples doc per @Fang- comments
c6b9bc1tinnus-napbus
arvo/eyre/examples.md+26−43
@@ -7,6 +7,7 @@ template = "doc.html"
7# Contents
7# Contents
8
8
9- [Introduction](#introduction)
9- [Introduction](#introduction)
10+- [Authenticating](#authenticating)
10- [Using the Channel System](#using-the-channel-system)
11- [Using the Channel System](#using-the-channel-system)
11- [Scrying](#scrying)
12- [Scrying](#scrying)
12- [Running Threads With Spider](#running-threads-with-spider)
13- [Running Threads With Spider](#running-threads-with-spider)
@@ -20,11 +21,11 @@ This documents contains practical examples of the various ways of interacting wi
20
21
21General documentation of the `task`s and methods described here are available in the [External API Reference](@/docs/arvo/eyre/external-api-ref.md) document and the [Internal API Reference](@/docs/arvo/eyre/tasks.md) document.
22General documentation of the `task`s and methods described here are available in the [External API Reference](@/docs/arvo/eyre/external-api-ref.md) document and the [Internal API Reference](@/docs/arvo/eyre/tasks.md) document.
22
23
23−# Using The Channel System
24+# Authenticating
24
25
25−Here we'll look at a practical example of Eyre's channel system. You can refer to the [Channels](@/docs/arvo/eyre/external-api-ref.md#channels) section of the [External API Reference](@/docs/arvo/eyre/external-api-ref.md) document for relevant details.
26+In most cases we must obtain a valid session cookie by [authenticating](@/docs/arvo/eyre/external-api-ref.md#authentication) with our web login code (which can be obtained by running `+code` in the dojo) before we can use Eyre's interfaces (such as the channel system or scry interface).
26
27
27−The first thing we need to do is obtain a session cookie by [authenticating](@/docs/arvo/eyre/external-api-ref.md#authentication) with our web login code, which you can get by running `+code` in the dojo. In our case we'll just use the default code for a fakezod.
28+Here we'll try authenticating with the default fakezod code.
28
29
29Using `curl` in the unix terminal, we'll make an HTTP POST request with `"password=<code>"` in the body:
30Using `curl` in the unix terminal, we'll make an HTTP POST request with `"password=<code>"` in the body:
30
31
@@ -42,6 +43,14 @@ Server: urbit/vere-1.5
42set-cookie: urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm; Path=/; Max-Age=604800
43set-cookie: urbauth-~zod=0v3.j2062.1prp1.qne4e.goq3h.ksudm; Path=/; Max-Age=604800
43```
44```
44
45
46+The `urbauth-....` cookie can be now be included in subsequent requests (e.g. to the channel system) by providing it in a Cookie HTTP header.
47+
48+# Using The Channel System
49+
50+Here we'll look at a practical example of Eyre's channel system. You can refer to the [Channels](@/docs/arvo/eyre/external-api-ref.md#channels) section of the [External API Reference](@/docs/arvo/eyre/external-api-ref.md) document for relevant details.
51+
52+First, we must obtain a session cookie by [authenticating](#authenticating).
53+
45Now that we have our cookie, we can try poking an app & simultaneously opening a new channel. In this case, we'll poke the `hood` app with a `mark` of `helm-hi` to print "Opening airlock" in the dojo.
54Now that we have our cookie, we can try poking an app & simultaneously opening a new channel. In this case, we'll poke the `hood` app with a `mark` of `helm-hi` to print "Opening airlock" in the dojo.
46
55
47We'll do this with an HTTP PUT request, and we'll include the cookie we obtained when we authenticated in the `Cookie` header. The URL path we'll make the request to will be `http://localhost:8080/~/channel/mychannel`. The last part of the path is the channel `UID` - the name for our new channel. Normally you'd use the current unix time plus a hash to ensure uniqueness, but in this case we'll just use `mychannel` for simplicity.
56We'll do this with an HTTP PUT request, and we'll include the cookie we obtained when we authenticated in the `Cookie` header. The URL path we'll make the request to will be `http://localhost:8080/~/channel/mychannel`. The last part of the path is the channel `UID` - the name for our new channel. Normally you'd use the current unix time plus a hash to ensure uniqueness, but in this case we'll just use `mychannel` for simplicity.
@@ -99,7 +108,7 @@ curl --header "Content-Type: application/json" \
99 http://localhost:8080/~/channel/my-channel
108 http://localhost:8080/~/channel/my-channel
100```
109```
101
110
102−Notice we've incremented the `id` to `2`, as request IDs must be sequential.
111+Notice we've incremented the `id` to `2`. Eyre doesn't require IDs to be sequential, merely numerical and unique, but sequential IDs are typically the most practical.
103
112
104Back in the event stream, we'll see a positive watch ack as a [subscribe](@/docs/arvo/eyre/external-api-ref.md#watch-ack) `response`, meaning the subscription has been successful:
113Back in the event stream, we'll see a positive watch ack as a [subscribe](@/docs/arvo/eyre/external-api-ref.md#watch-ack) `response`, meaning the subscription has been successful:
105
114
@@ -108,14 +117,14 @@ id: 1
108data: {"ok":"ok","id":2,"response":"subscribe"}
117data: {"ok":"ok","id":2,"response":"subscribe"}
109```
118```
110
119
111−Now we'll try trigger an event on our event stream. In fakezod's landscape, create a new chat channel named "test". You should see the `fact` containing the `add-graph` `graph-update` come through on our channel in a [diff](@/docs/arvo/eyre/external-api-ref.md#diff) `response`:
120+Now we'll try trigger an event on our event stream. In fakezod's landscape, create a new chat channel named "test". You should see the `add-graph` `graph-update` come through on our channel in a [diff](@/docs/arvo/eyre/external-api-ref.md#diff) `response`:
112
121
113```
122```
114id: 2
123id: 2
115data: {"json":{"graph-update":{"add-graph":{"graph":{},"resource":{"name":"test-1183","ship":"zod"},"mark":"graph-validator-chat","overwrite":false}}},"id":2,"response":"diff"}
124data: {"json":{"graph-update":{"add-graph":{"graph":{},"resource":{"name":"test-1183","ship":"zod"},"mark":"graph-validator-chat","overwrite":false}}},"id":2,"response":"diff"}
116```
125```
117
126
118−All `fact`s we receive must be acked so Eyre knows we've successfully received it. To do this we'll send an [ack](@/docs/arvo/eyre/external-api-ref.md#ack) `action` which specifies the `event-id` of the event in question - `2` in this case:
127+All events we receive must be `ack`ed so Eyre knows we've successfully received them. To do this we'll send an [ack](@/docs/arvo/eyre/external-api-ref.md#ack) `action` which specifies the `event-id` of the event in question - `2` in this case:
119
128
120```
129```
121curl --header "Content-Type: application/json" \
130curl --header "Content-Type: application/json" \
@@ -125,7 +134,9 @@ curl --header "Content-Type: application/json" \
125 http://localhost:8080/~/channel/my-channel
134 http://localhost:8080/~/channel/my-channel
126```
135```
127
136
137+This same pattern would be repeated for all subsequent events. Note that when you `ack` one event, you also implicitly `ack` all previous events, so in this case event `1` will also be `ack`ed.
138+
128−This same pattern would be repeated for all subsequent `fact`s. When we're finished, we can unsubscribe from `graph-store` `/update`. We do this by sending Eyre a [unsubscribe](@/docs/arvo/eyre/external-api-ref.md#unsubscribe) `action`, and specify the request ID of the original `subscribe` `action` in the `subscription` field - `2` in our case:
139+When we're finished, we can unsubscribe from `graph-store` `/update`. We do this by sending Eyre a [unsubscribe](@/docs/arvo/eyre/external-api-ref.md#unsubscribe) `action`, and specify the request ID of the original `subscribe` `action` in the `subscription` field - `2` in our case:
129
140
130```
141```
131curl --header "Content-Type: application/json" \
142curl --header "Content-Type: application/json" \
@@ -135,7 +146,7 @@ curl --header "Content-Type: application/json" \
135 http://localhost:8080/~/channel/my-channel
146 http://localhost:8080/~/channel/my-channel
136```
147```
137
148
138−Unlike `poke` and `subscribe` actions, Eyre doesn't ack `unsubscribe`s, but we'll now have stopped receiving `fact`s from `graph-store`.
149+Unlike `poke` and `subscribe` actions, Eyre doesn't acknowledge `unsubscribe`s, but we'll now have stopped receiving updates from `graph-store`.
139
150
140Finally, let's close the channel itself. We can do this simply by sending Eyre a [delete](@/docs/arvo/eyre/external-api-ref.md#delete-channel) `action`:
151Finally, let's close the channel itself. We can do this simply by sending Eyre a [delete](@/docs/arvo/eyre/external-api-ref.md#delete-channel) `action`:
141
152
@@ -153,21 +164,7 @@ With our channel deleted, we can now close the connection on the client side.
153
164
154Here we'll look at performing scries through Eyre. You can refer to the [Scry](@/docs/arvo/eyre/external-api-ref.md#scry) section of the [External API Reference](@/docs/arvo/eyre/external-api-ref.md) document for relevant details.
165Here we'll look at performing scries through Eyre. You can refer to the [Scry](@/docs/arvo/eyre/external-api-ref.md#scry) section of the [External API Reference](@/docs/arvo/eyre/external-api-ref.md) document for relevant details.
155
166
156−The first thing we must do is obtain a session cookie by authenticating with our web login code. We'll use the unix `curl` utility and provide the default code for a fakezod:
167+First we must obtain a session cookie by [authenticating](#authenticating).
157−
158−```
159−curl -i localhost:8080/~/login -X POST -d "password=lidlut-tabwed-pillex-ridrup"
160−```
161−
162−Eyre will respond with HTTP status 204 and a `set-cookie` header containing the cookie, which we'll use in the `cookie` header of subsequent requests:
163−
164−```
165−HTTP/1.1 204 ok
166−Date: Fri, 04 Jun 2021 10:15:15 GMT
167−Connection: keep-alive
168−Server: urbit/vere-1.5
169−set-cookie: urbauth-~zod=0v1.1pseu.tq7hs.hps2t.ltaf1.tmqjm; Path=/; Max-Age=604800
170−```
171
168
172Having obtained a cookie, we can now try a scry. We'll scry the `graph-store` Gall agent on the `/x/keys` scry path, which will return the list of channels it has. If you don't already have any chat channels on your fakezod, go ahead and create one via landscape so it'll have something to return.
169Having obtained a cookie, we can now try a scry. We'll scry the `graph-store` Gall agent on the `/x/keys` scry path, which will return the list of channels it has. If you don't already have any chat channels on your fakezod, go ahead and create one via landscape so it'll have something to return.
173
170
@@ -237,21 +234,7 @@ Here's an extremely simple thread that takes a `vase` of `(unit json)` and just
237(pure:m !>(json))
234(pure:m !>(json))
238```
235```
239
236
240−In order to run it through Eyre, we must first obtain a session cookie by [authenticating](@/docs/arvo/eyre/external-api-ref.md#authentication) with our web login code. To do so, we'll make an HTTP POST request using the unix `curl` utility:
237+First we must obtain a session cookie by [authenticating](#authenticating).
241−
242−```
243−curl -i localhost:8080/~/login -X POST -d "password=lidlut-tabwed-pillex-ridrup"
244−```
245−
246−Eyre will respond with a 204 status and a `set-cookie` header containing the cookie:
247−
248−```
249−HTTP/1.1 204 ok
250−Date: Sun, 06 Jun 2021 04:50:09 GMT
251−Connection: keep-alive
252−Server: urbit/vere-1.5
253−set-cookie: urbauth-~zod=0v6.h6t4q.2tkui.oeaqu.nihh9.i0qv6; Path=/; Max-Age=604800
254−```
255
238
256Now we can try and run our thread. Spider (the Gall agent that manages threads) is bound to the `/spider` URL path, and expects the rest of the path to be `/{inputMark}/{thread}/{outputMark}`. Our `{thread}` is called `eyre-thread`, and both its `{inputMark}` and `{outputMark}` are `json`, so our URL path will be `/spider/json/eyre-agent/json`. Our request will be an HTTP POST request and the body will be some `json`, in this case `[{"foo": "bar"}]`:
239Now we can try and run our thread. Spider (the Gall agent that manages threads) is bound to the `/spider` URL path, and expects the rest of the path to be `/{inputMark}/{thread}/{outputMark}`. Our `{thread}` is called `eyre-thread`, and both its `{inputMark}` and `{outputMark}` are `json`, so our URL path will be `/spider/json/eyre-agent/json`. Our request will be an HTTP POST request and the body will be some `json`, in this case `[{"foo": "bar"}]`:
257
240
@@ -283,7 +266,7 @@ In many cases you'll just want to interact with Gall agents through the JSON API
283
266
284You can refer to the [%connect](@/docs/arvo/eyre/tasks.md#connect) section of the [Internal API Reference](@/docs/arvo/eyre/tasks.md) document for relevant details.
267You can refer to the [%connect](@/docs/arvo/eyre/tasks.md#connect) section of the [Internal API Reference](@/docs/arvo/eyre/tasks.md) document for relevant details.
285
268
286−Here's a Gall agent that demonstrates this method. It binds the URL path `/foo`, serves `<h1>Hello, World!</h1>` for GET requests and a `405` error for all others. It also prints information to the dojo as various things happen.
269+Here's a Gall agent that demonstrates this method. It binds the URL path `/foo`, serves `<h1>Hello, World!</h1>` for GET requests and a `405` error for all others. It also prints debug information to the terminal as various things happen.
287
270
288`eyre-agent.hoon`
271`eyre-agent.hoon`
289
272
@@ -320,7 +303,7 @@ Here's a Gall agent that demonstrates this method. It binds the URL path `/foo`,
320 =/ data=octs
303 =/ data=octs
321 (as-octs:mimes:html '<h1>405 Method Not Allowed</h1>')
304 (as-octs:mimes:html '<h1>405 Method Not Allowed</h1>')
322 =/ content-length=@t
305 =/ content-length=@t
323− (crip (skip (scow %ud p.data) |=(a=@tD =(a '.'))))
306+ (crip ((d-co:co 1) p.data))
324 =/ =response-header:http
307 =/ =response-header:http
325 :- 405
308 :- 405
326 :~ ['Content-Length' content-length]
309 :~ ['Content-Length' content-length]
@@ -338,7 +321,7 @@ Here's a Gall agent that demonstrates this method. It binds the URL path `/foo`,
338 =/ data=octs
321 =/ data=octs
339 (as-octs:mimes:html '<h1>Hello, World!</h1>')
322 (as-octs:mimes:html '<h1>Hello, World!</h1>')
340 =/ content-length=@t
323 =/ content-length=@t
341− (crip (skip (scow %ud p.data) |=(a=@tD =(a '.'))))
324+ (crip ((d-co:co 1) p.data))
342 =/ =response-header:http
325 =/ =response-header:http
343 :- 200
326 :- 200
344 :~ ['Content-Length' content-length]
327 :~ ['Content-Length' content-length]
@@ -453,7 +436,7 @@ transfer-encoding: chunked
453=/ data=octs
436=/ data=octs
454 (as-octs:mimes:html '<h1>Hello, World!</h1>')
437 (as-octs:mimes:html '<h1>Hello, World!</h1>')
455=/ content-length=@t
438=/ content-length=@t
456− (crip (skip (scow %ud p.data) |=(a=@tD =(a '.'))))
439+ (crip ((d-co:co 1) p.data))
457=/ =response-header:http
440=/ =response-header:http
458 :- 200
441 :- 200
459 :~ ['Content-Length' content-length]
442 :~ ['Content-Length' content-length]
@@ -520,7 +503,7 @@ Here's a very simple generator that will just echo back the body of the request
520=/ data=octs
503=/ data=octs
521 (as-octs:mimes:html msg)
504 (as-octs:mimes:html msg)
522=/ content-length=@t
505=/ content-length=@t
523− (rsh [3 2] (scot %ui p.data))
506+ (crip ((d-co:co 1) p.data))
524=/ =response-header:http
507=/ =response-header:http
525 :- 200
508 :- 200
526 :~ ['Content-Length' content-length]
509 :~ ['Content-Length' content-length]