Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add session based auth workflow #464

Merged
merged 14 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions docs/examples/gallery_streaming.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,29 +107,30 @@ def answer(self, messages):

config = Config(assistants=[DemoStreamingAssistant])

rest_api = ragna_docs.RestApi()
ragna_deploy = ragna_docs.RagnaDeploy(config)

client, document = rest_api.start(config, authenticate=True, upload_document=True)
client, document = ragna_deploy.get_http_client(
authenticate=True, upload_document=True
)

# %%
# Start and prepare the chat

chat = (
client.post(
"/chats",
"/api/chats",
json={
"name": "Tutorial REST API",
"documents": [document],
"document_ids": [document["id"]],
"source_storage": source_storages.RagnaDemoSourceStorage.display_name(),
"assistant": DemoStreamingAssistant.display_name(),
"params": {},
},
)
.raise_for_status()
.json()
)

client.post(f"/chats/{chat['id']}/prepare").raise_for_status()
client.post(f"/api/chats/{chat['id']}/prepare").raise_for_status()

# %%
# Streaming the response is performed with [JSONL](https://jsonlines.org/). Each line
Expand All @@ -140,7 +141,7 @@ def answer(self, messages):

with client.stream(
"POST",
f"/chats/{chat['id']}/answer",
f"/api/chats/{chat['id']}/answer",
json={"prompt": "What is Ragna?", "stream": True},
) as response:
chunks = [json.loads(data) for data in response.iter_lines()]
Expand All @@ -163,7 +164,8 @@ def answer(self, messages):
print("".join(chunk["content"] for chunk in chunks))

# %%
# Before we close the example, let's stop the REST API and have a look at what would
# have printed in the terminal if we had started it with the `ragna api` command.
# Before we close the example, let's terminate the REST API and have a look at what
# would have printed in the terminal if we had started it with the `ragna deploy`
# command.

rest_api.stop()
ragna_deploy.terminate()
38 changes: 8 additions & 30 deletions docs/references/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ is equivalent to `RAGNA_API_ORIGINS='["http://localhost:31477"]'`.

Local root directory Ragna uses for storing files. See [ragna.local_root][].

### `authentication`
### `auth`

[ragna.deploy.Authentication][] class to use for authenticating users.
[ragna.deploy.Auth][] class to use for authenticating users.

### `document`

Expand All @@ -85,48 +85,26 @@ Local root directory Ragna uses for storing files. See [ragna.local_root][].

[ragna.core.Assistant][]s to be available for the user to use.

### `api`

#### `hostname`
### `hostname`

Hostname the REST API will be bound to.

#### `port`
### `port`

Port the REST API will be bound to.

#### `root_path`
### `root_path`

A path prefix handled by a proxy that is not seen by the REST API, but is seen by
external clients.

#### `url`

URL of the REST API to be accessed by the web UI. Make sure to include the
[`root_path`](#root_path) if set.

#### `origins`
### `origins`

[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) origins that are allowed
to connect to the REST API. The URL of the web UI is required for it to function.
to connect to the REST API.

#### `database_url`
### `database_url`

URL of a SQL database that will be used to store the Ragna state. See
[SQLAlchemy documentation](https://docs.sqlalchemy.org/en/20/core/engines.html#database-urls)
on how to format the URL.

### `ui`

#### `hostname`

Hostname the web UI will be bound to.

#### `port`

Port the web UI will be bound to.

#### `origins`

[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) origins that are allowed
to connect to the web UI.
2 changes: 1 addition & 1 deletion docs/references/rest-api.md → docs/references/deploy.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# REST API reference

<!--
Generated using assets/openapi.json - a copy of the autogenerated spec by FAastAPI, ref: https://fastapi.tiangolo.com/features/#automatic-docs
Generated using assets/openapi.json - a copy of the autogenerated spec by FastAPI, ref: https://fastapi.tiangolo.com/features/#automatic-docs

Presented using Swagger UI, ref: https://swagger.io/tools/swagger-ui/
-->
Expand Down
6 changes: 3 additions & 3 deletions docs/references/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,9 @@
</tr>
</table>

- The classes [ragna.deploy.Authentication][], [ragna.deploy.RagnaDemoAuthentication][],
and [ragna.deploy.Config][] moved from the [ragna.core][] module to a new
[ragna.deploy][] module.
- The classes `ragna.deploy.Authentication`, `ragna.deploy.RagnaDemoAuthentication`, and
[ragna.deploy.Config][] moved from the [ragna.core][] module to a new [ragna.deploy][]
module.
- [ragna.core.Component][], which is the superclass for [ragna.core.Assistant][] and
[ragna.core.SourceStorage][], no longer takes a [ragna.deploy.Config][] to
instantiate. For example
Expand Down
36 changes: 19 additions & 17 deletions docs/tutorials/gallery_custom_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,11 @@ def answer(self, messages: list[Message]) -> Iterator[str]:
assistants=[TutorialAssistant],
)

rest_api = ragna_docs.RestApi()
ragna_deploy = ragna_docs.RagnaDeploy(config)

client, document = rest_api.start(config, authenticate=True, upload_document=True)
client, document = ragna_deploy.get_http_client(
authenticate=True, upload_document=True
)

# %%
# To select our custom components, we pass their display names to the chat creation.
Expand All @@ -201,21 +203,21 @@ def answer(self, messages: list[Message]) -> Iterator[str]:
import json

response = client.post(
"/chats",
"/api/chats",
json={
"name": "Tutorial REST API",
"documents": [document],
"document_ids": [document["id"]],
"source_storage": TutorialSourceStorage.display_name(),
"assistant": TutorialAssistant.display_name(),
"params": {},
},
).raise_for_status()
chat = response.json()

client.post(f"/chats/{chat['id']}/prepare").raise_for_status()
client.post(f"/api/chats/{chat['id']}/prepare").raise_for_status()

response = client.post(
f"/chats/{chat['id']}/answer",
f"/api/chats/{chat['id']}/answer",
json={"prompt": "What is Ragna?"},
).raise_for_status()
answer = response.json()
Expand All @@ -225,7 +227,7 @@ def answer(self, messages: list[Message]) -> Iterator[str]:
# Let's stop the REST API and have a look at what would have printed in the terminal if
# we had started it with the `ragna api` command.

rest_api.stop()
ragna_deploy.terminate()

# %%
# ### Web UI
Expand Down Expand Up @@ -263,9 +265,7 @@ def answer(
my_optional_parameter: str = "foo",
) -> Iterator[str]:
print(f"Running {type(self).__name__}().answer()")
yield (
f"I was given {my_required_parameter=} and {my_optional_parameter=}."
)
yield f"I was given {my_required_parameter=} and {my_optional_parameter=}."


# %%
Expand Down Expand Up @@ -319,19 +319,21 @@ def answer(
assistants=[ElaborateTutorialAssistant],
)

rest_api = ragna_docs.RestApi()
ragna_deploy = ragna_docs.RagnaDeploy(config)

client, document = rest_api.start(config, authenticate=True, upload_document=True)
client, document = ragna_deploy.get_http_client(
authenticate=True, upload_document=True
)

# %%
# To pass custom parameters, define them in the `params` mapping when creating a new
# chat.

response = client.post(
"/chats",
"/api/chats",
json={
"name": "Tutorial REST API",
"documents": [document],
"document_ids": [document["id"]],
"source_storage": TutorialSourceStorage.display_name(),
"assistant": ElaborateTutorialAssistant.display_name(),
"params": {
Expand All @@ -344,10 +346,10 @@ def answer(

# %%

client.post(f"/chats/{chat['id']}/prepare").raise_for_status()
client.post(f"/api/chats/{chat['id']}/prepare").raise_for_status()

response = client.post(
f"/chats/{chat['id']}/answer",
f"/api/chats/{chat['id']}/answer",
json={"prompt": "What is Ragna?"},
).raise_for_status()
answer = response.json()
Expand All @@ -357,7 +359,7 @@ def answer(
# Let's stop the REST API and have a look at what would have printed in the terminal if
# we had started it with the `ragna api` command.

rest_api.stop()
ragna_deploy.terminate()

# %%
# ### Web UI
Expand Down
Loading
Loading