Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ examples/**/dataset/**
# Flower Baselines
baselines/datasets/leaf

# Swift auto-generated documentation
Documentation

# Exclude ee package
src/py/flwr/ee

Expand Down
2 changes: 2 additions & 0 deletions intelligence/dev/build-docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
set -e
cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"/../

python3 dev/build-example-docs.py

# Build TS docs
cd ts && \
pnpm build:docs --readme none --name "TypeScript API" && \
Expand Down
150 changes: 150 additions & 0 deletions intelligence/dev/build-example-docs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# Copyright 2025 Flower Labs GmbH. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Build the examples docs."""

import os
import re
import shutil

from pathlib import Path

ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
INDEX = os.path.join(ROOT, "docs", "source", "examples.rst")

initial_text = """
Examples
========

Below you will find a list of Flower Intelligence examples for Node.js and one
for web apps.

Node.js Examples
----------------

Those examples will run in the terminal and are mostly there to showcase some
features with very low overhead. You'll find more instruction in the
respective pages.

"""

table_headers = (
"\n.. list-table::\n :widths: 50 45 \n "
":header-rows: 1\n\n * - Title\n - Tags\n\n"
)

categories = {
"node": {"table": table_headers, "list": ""},
"web": {"table": table_headers, "list": ""},
}


def _read_metadata(example):
with open(os.path.join(example, "README.md")) as f:
content = f.read()

metadata_match = re.search(r"^---(.*?)^---", content, re.DOTALL | re.MULTILINE)
if not metadata_match:
raise ValueError("Metadata block not found")
metadata = metadata_match.group(1)

title_match = re.search(r"^# (.+)$", content, re.MULTILINE)
if not title_match:
raise ValueError("Title not found in metadata")
title = title_match.group(1).strip()

tags_match = re.search(r"^tags:\s*\[(.+?)\]$", metadata, re.MULTILINE)
if not tags_match:
raise ValueError("Tags not found in metadata")
tags = tags_match.group(1).strip()

return title, tags


def _add_table_entry(example, tag, table_var):
title, tags = _read_metadata(example)
example_name = Path(example).stem
table_entry = f" * - `{title} <{example_name}.html>`_ \n - {tags}\n\n"
if tag in tags:
categories[table_var]["table"] += table_entry
categories[table_var]["list"] += f" {example_name}\n"
return True
return False


def _copy_markdown_files(example):
for file in os.listdir(example):
if file.endswith(".md"):
src = os.path.join(example, file)
dest = os.path.join(
ROOT, "docs", "source", os.path.basename(example) + ".md"
)
shutil.copyfile(src, dest)


def _add_gh_button(example):
gh_text = f'[<img src="_static/view-gh.png" alt="View on GitHub" width="200"/>](https://github.com/adap/flower/blob/main/intelligence/ts/examples/{example})'
readme_file = os.path.join(ROOT, "docs", "source", example + ".md")
with open(readme_file, "r+") as f:
content = f.read()
if gh_text not in content:
content = re.sub(
r"(^# .+$)", rf"\1\n\n{gh_text}", content, count=1, flags=re.MULTILINE
)
f.seek(0)
f.write(content)
f.truncate()


def _main():
if os.path.exists(INDEX):
os.remove(INDEX)

with open(INDEX, "w") as index_file:
index_file.write(initial_text)

examples_dir = os.path.join(ROOT, "ts", "examples")
for example in sorted(os.listdir(examples_dir)):
example_path = os.path.join(examples_dir, example)
if os.path.isdir(example_path):
_copy_markdown_files(example_path)
_add_gh_button(example)
if not _add_table_entry(example_path, "node", "node"):
_add_table_entry(example_path, "web", "web")

with open(INDEX, "a") as index_file:
index_file.write(categories["node"]["table"])

index_file.write("\nWeb Examples\n------------\n")
index_file.write(
"Those examples will require you to use a browser. You'll find "
"more instructions in the respective pages.\n"
)
index_file.write(categories["web"]["table"])

index_file.write(
"\n.. toctree::\n :maxdepth: 1\n :caption: Quickstart\n :hidden:\n\n"
)
index_file.write(categories["node"]["list"])

index_file.write(
"\n.. toctree::\n :maxdepth: 1\n :caption: Advanced\n :hidden:\n\n"
)
index_file.write(categories["web"]["list"])

index_file.write("\n")


if __name__ == "__main__":
_main()
2 changes: 2 additions & 0 deletions intelligence/docs/source/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
ts-api-ref/
swift-api-ref/
*.md
examples.rst
Binary file added intelligence/docs/source/_static/view-gh.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions intelligence/docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,7 @@ Information-oriented API reference and other reference material.
:caption: Reference docs

ref-models
examples
ts-api-ref/index

Join the Flower Community
Expand Down
42 changes: 34 additions & 8 deletions intelligence/ts/examples/browser-extension/README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,38 @@
# Flower Intelligence Flower Extension Example
---
tags: [web, browser, extension, chat, typescript]
---

## Dev Notes
# Browser Extension Example

- The `watch` script relies on [entr](https://github.com/eradman/entr).
- You can use `npm` or `pnpm` (or probably `yarn`), but this README shows examples using `pnpm`
You can use `npm` or `pnpm` (or probably `yarn`), but this README shows examples using `pnpm`

Install dependencies: `pnpm i`
## Project setup

In order to use remote handoff, copy `.env.example` into `.env` and update the API keys and IDs inside it.
You must first download the example with the following command:

Build with:
```bash
git clone --depth=1 https://github.com/adap/flower.git _tmp && mv _tmp/intelligence/ts/examples/encrypted . && rm -rf _tmp && cd encrypted
```

```sh
You can then install the project dependencies with:

```bash
pnpm i
```

```{note}
The `watch` script relies on [entr](https://github.com/eradman/entr).
```

```{warning}
In order to use remote handoff, copy `.env.example` into `.env` and update the API key inside it (if you don't have a valid API key, you can register [here](https://flower.ai/intelligence/)).
```

## Build

Then, you need to build the project:

```bash
pnpm build
```

Expand All @@ -21,3 +42,8 @@ Or rebuild when files change:
# Make sure to install this first: https://github.com/eradman/entr
pnpm watch
```

## Run

Once you have built the project, you should find the web-extension content that
can be imported into a browser in `dist/`.
3 changes: 1 addition & 2 deletions intelligence/ts/examples/browser-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
"format:check": "prettier --check .",
"lint": "eslint --fix src",
"lint:check": "eslint src",
"ibuild": "pnpm i && pnpm build",
"build:extension": "pnpm ibuild && cd dist && zip -r -FS ./flower-intelligence-browser-assistant.xpi * && cd .."
"ibuild": "pnpm i && pnpm build"
},
"dependencies": {
"@flwr/flwr": "^0.1.3",
Expand Down
44 changes: 38 additions & 6 deletions intelligence/ts/examples/encrypted/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,45 @@
# Flower Intelligence Encrypted Example
---
tags: [node, minimal, remote, encryption, Flower Confidential Remote Compute, typescript]
---

In order to run this example, update the following values inside `src/index.ts`:
# Flower Confidential Remote Compute example

```typescript
fi.apiKey = 'REPLACE_HERE';
You can use `npm` or `pnpm` (or probably `yarn`), but this README shows examples using `pnpm`

## Project setup

You must first download the example with the following command:

```bash
git clone --depth=1 https://github.com/adap/flower.git _tmp && mv _tmp/intelligence/ts/examples/encrypted . && rm -rf _tmp && cd encrypted
```

You can then install the project dependencies with:

```bash
pnpm i
```

```{warning}
In order to run this example, you need to update `fi.apiKey = 'REPLACE_HERE'` inside `src/index.ts` with a valid API key (if you don't have one, you can register [here](https://flower.ai/intelligence/)).
```

Run example:
## Build

Then, you need to build the project:

```bash
pnpm start
pnpm build
```

## Run

In order to run the example once the project has been built:

```bash
node dist/index.js
```

```{note}
You can also use `pnpm start` to perform the installation, build, and run steps at the same time.
```
40 changes: 37 additions & 3 deletions intelligence/ts/examples/hello-world-js/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,41 @@
# Flower Intelligence "Hello, World!" Example Project
---
tags: [node, minimal, javascript]
---

Run example:
# "Hello, World!" JavaScript Project

You can use `npm` or `pnpm` (or probably `yarn`), but this README shows examples using `pnpm`

## Project setup

You must first download the example with the following command:

```bash
git clone --depth=1 https://github.com/adap/flower.git _tmp && mv _tmp/intelligence/ts/examples/hello-world-js . && rm -rf _tmp && cd hello-world-js
```

You can then install the project dependencies with:

```bash
pnpm start
pnpm i
```

## Build

If you want to build the project, you can use:

```bash
pnpm build
```

## Run

In order to run the example once the project has been built:

```bash
node dist/index.js
```

```{note}
You can also use `pnpm start` to perform the installation, build, and run steps at the same time.
```
40 changes: 37 additions & 3 deletions intelligence/ts/examples/hello-world-ts/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,41 @@
# Flower Intelligence "Hello, World!" TypeScript Example
---
tags: [node, minimal, typescript]
---

Run example:
# "Hello, World!" TypeScript Project

You can use `npm` or `pnpm` (or probably `yarn`), but this README shows examples using `pnpm`

## Project setup

You must first download the example with the following command:

```bash
git clone --depth=1 https://github.com/adap/flower.git _tmp && mv _tmp/intelligence/ts/examples/hello-world-ts . && rm -rf _tmp && cd hello-world-ts
```

You can then install the project dependencies with:

```bash
pnpm start
pnpm i
```

## Build

If you want to build the project, you can use:

```bash
pnpm build
```

## Run

In order to run the example once the project has been built:

```bash
node dist/index.js
```

```{note}
You can also use `pnpm start` to perform the installation, build, and run steps at the same time.
```
Loading
Loading