-
Notifications
You must be signed in to change notification settings - Fork 942
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
docs(examples) Add table and improve design #3688
Merged
Merged
Changes from all commits
Commits
Show all changes
70 commits
Select commit
Hold shift + click to select a range
75b8669
docs(examples:skip) Improve example docs generation script
charlesbvll 509e2e3
Test script
charlesbvll 2b9fc1d
fix script
charlesbvll 07a4039
Add initial metadata
charlesbvll 9430011
Use metadata
charlesbvll ee0394b
Fix script
charlesbvll ee01e6b
Update metadata
charlesbvll 7dea640
Update metadata
charlesbvll 35c98b7
Update metadata
charlesbvll b885819
Remove index from history
charlesbvll 983d086
Update some metadata
charlesbvll 15bd6d6
Update metadata
charlesbvll b85d117
Update metadata
charlesbvll 2769eec
Update metadata
charlesbvll 1606179
Update metatdata
charlesbvll c5c7d29
Remove URL
charlesbvll efcd732
Remove URL handling
charlesbvll af17161
Improve format and add dscription to table
charlesbvll 0baefdc
Separate tables
charlesbvll 5b0cda8
Capitalize Cp
charlesbvll acc5bf2
Add Python script
charlesbvll 301d9d4
Update metadata
charlesbvll 0db320e
Update metadata
charlesbvll c4e2263
Try markdown format
charlesbvll f4db217
Test with quotes
charlesbvll 3a073a6
Remove quotes
charlesbvll 2f59185
Update MNIST
charlesbvll 78b7ca3
Try quotes markdown
charlesbvll 72d9946
Try simple string
charlesbvll 9020e9e
use pipe
charlesbvll a5266b8
Fix MNIST metadata format
charlesbvll 919798f
Update rest of metadata
charlesbvll 0eecd2a
Fix script
charlesbvll ccf76a0
Update Cifar metadata
charlesbvll 0c0a198
Use HF for MNIST link
charlesbvll 9e41df7
Remove quotes
charlesbvll 21f02e2
Update iris and MedNist
charlesbvll 319bc11
Update metadata
charlesbvll 8a4b26b
Update metadata
charlesbvll d749720
Support lists of tags
charlesbvll 24be99c
Update metadata
charlesbvll 9bcf90f
Update scikit-learn
charlesbvll 56005ba
Update torchvision metadata
charlesbvll 2b79e98
Update torch metadata
charlesbvll 207c373
Add link to xgboost
charlesbvll 604fe0b
Update metadata
charlesbvll 81e7b12
Add building to script
charlesbvll a169a59
Add keras link
charlesbvll bdd2ba9
Update metadata
charlesbvll 4d593ce
Add metadata
charlesbvll 5ac931a
Shorten mods
charlesbvll 105c4e9
Remove locale
charlesbvll dd29d27
Update metadata
charlesbvll 91f1e17
Merge branch 'main' into improve-example-docs-script
charlesbvll d4dfb7a
Merge branch 'main' into improve-example-docs-script
charlesbvll 3f5f35a
Format README files and update script
charlesbvll 1b8f436
Update build-docs script
charlesbvll 6f4dd4e
Use numbers
charlesbvll b2fd515
Remove deprecated script
charlesbvll dd55736
Add copyright notice and reformat
charlesbvll 3427e22
Add error handling
charlesbvll 1206087
Allow no dataset or framework
charlesbvll 9c471b7
Update examples/fl-dp-sa/README.md
charlesbvll c40f440
Update examples/fl-tabular/README.md
charlesbvll d69dae4
Update examples/flower-via-docker-compose/README.md
charlesbvll e4b316f
Update examples/llm-flowertune/README.md
charlesbvll d30ffcd
Update examples/embedded-devices/README.md
charlesbvll 542f0a4
Merge branch 'main' into improve-example-docs-script
charlesbvll c91408d
Merge branch 'main' into improve-example-docs-script
danieljanes 5fad5a8
Update dev/build-example-docs.py
danieljanes File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,236 @@ | ||
# Copyright 2024 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 Flower Example docs.""" | ||
|
||
import os | ||
import shutil | ||
import re | ||
import subprocess | ||
from pathlib import Path | ||
|
||
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) | ||
INDEX = os.path.join(ROOT, "examples", "doc", "source", "index.rst") | ||
|
||
initial_text = """ | ||
Flower Examples Documentation | ||
----------------------------- | ||
|
||
Welcome to Flower Examples' documentation. `Flower <https://flower.ai>`_ is | ||
a friendly federated learning framework. | ||
|
||
Join the Flower Community | ||
------------------------- | ||
|
||
The Flower Community is growing quickly - we're a friendly group of researchers, | ||
engineers, students, professionals, academics, and other enthusiasts. | ||
|
||
.. button-link:: https://flower.ai/join-slack | ||
:color: primary | ||
:shadow: | ||
|
||
Join us on Slack | ||
|
||
Quickstart Examples | ||
------------------- | ||
|
||
Flower Quickstart Examples are a collection of demo projects that show how you | ||
can use Flower in combination with other existing frameworks or technologies. | ||
|
||
""" | ||
|
||
table_headers = ( | ||
"\n.. list-table::\n :widths: 50 15 15 15\n " | ||
":header-rows: 1\n\n * - Title\n - Framework\n - Dataset\n - Tags\n\n" | ||
) | ||
|
||
categories = { | ||
"quickstart": {"table": table_headers, "list": ""}, | ||
"advanced": {"table": table_headers, "list": ""}, | ||
"other": {"table": table_headers, "list": ""}, | ||
} | ||
|
||
|
||
def _convert_to_link(search_result): | ||
if "|" in search_result: | ||
if "," in search_result: | ||
result = "" | ||
for part in search_result.split(","): | ||
result += f"{_convert_to_link(part)}, " | ||
return result[:-2] | ||
|
||
name, url = search_result.replace('"', "").split("|") | ||
return f"`{name.strip()} <{url.strip()}>`_" | ||
|
||
return search_result | ||
|
||
|
||
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"^title:\s*(.+)$", metadata, re.MULTILINE) | ||
if not title_match: | ||
raise ValueError("Title not found in metadata") | ||
title = title_match.group(1).strip() | ||
|
||
labels_match = re.search(r"^labels:\s*\[(.+?)\]$", metadata, re.MULTILINE) | ||
if not labels_match: | ||
raise ValueError("Labels not found in metadata") | ||
labels = labels_match.group(1).strip() | ||
|
||
dataset_match = re.search( | ||
r"^dataset:\s*\[(.*?)\]$", metadata, re.DOTALL | re.MULTILINE | ||
) | ||
if not dataset_match: | ||
raise ValueError("Dataset not found in metadata") | ||
dataset = dataset_match.group(1).strip() | ||
|
||
framework_match = re.search( | ||
r"^framework:\s*\[(.*?|)\]$", metadata, re.DOTALL | re.MULTILINE | ||
) | ||
if not framework_match: | ||
raise ValueError("Framework not found in metadata") | ||
framework = framework_match.group(1).strip() | ||
|
||
dataset = _convert_to_link(re.sub(r"\s+", " ", dataset).strip()) | ||
framework = _convert_to_link(re.sub(r"\s+", " ", framework).strip()) | ||
return title, labels, dataset, framework | ||
|
||
|
||
def _add_table_entry(example, label, table_var): | ||
title, labels, dataset, framework = _read_metadata(example) | ||
example_name = Path(example).stem | ||
table_entry = ( | ||
f" * - `{title} <{example_name}.html>`_ \n " | ||
f"- {framework} \n - {dataset} \n - {labels}\n\n" | ||
) | ||
if label in labels: | ||
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, "examples", "doc", "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/examples/{example})' | ||
readme_file = os.path.join(ROOT, "examples", "doc", "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 _copy_images(example): | ||
static_dir = os.path.join(example, "_static") | ||
dest_dir = os.path.join(ROOT, "examples", "doc", "source", "_static") | ||
if os.path.isdir(static_dir): | ||
for file in os.listdir(static_dir): | ||
if file.endswith((".jpg", ".png", ".jpeg")): | ||
shutil.copyfile( | ||
os.path.join(static_dir, file), os.path.join(dest_dir, file) | ||
) | ||
|
||
|
||
def _add_all_entries(index_file): | ||
examples_dir = os.path.join(ROOT, "examples") | ||
for example in sorted(os.listdir(examples_dir)): | ||
example_path = os.path.join(examples_dir, example) | ||
if os.path.isdir(example_path) and example != "doc": | ||
_copy_markdown_files(example_path) | ||
_add_gh_button(example) | ||
_copy_images(example) | ||
|
||
|
||
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, "examples") | ||
for example in sorted(os.listdir(examples_dir)): | ||
example_path = os.path.join(examples_dir, example) | ||
if os.path.isdir(example_path) and example != "doc": | ||
_copy_markdown_files(example_path) | ||
_add_gh_button(example) | ||
_copy_images(example_path) | ||
if not _add_table_entry(example_path, "quickstart", "quickstart"): | ||
if not _add_table_entry(example_path, "comprehensive", "comprehensive"): | ||
if not _add_table_entry(example_path, "advanced", "advanced"): | ||
_add_table_entry(example_path, "", "other") | ||
|
||
with open(INDEX, "a") as index_file: | ||
index_file.write(categories["quickstart"]["table"]) | ||
|
||
index_file.write("\nAdvanced Examples\n-----------------\n") | ||
index_file.write( | ||
"Advanced Examples are mostly for users that are both familiar with " | ||
"Federated Learning but also somewhat familiar with Flower's main " | ||
"features.\n" | ||
) | ||
index_file.write(categories["advanced"]["table"]) | ||
|
||
index_file.write("\nOther Examples\n--------------\n") | ||
index_file.write( | ||
"Flower Examples are a collection of example projects written with " | ||
"Flower that explore different domains and features. You can check " | ||
"which examples already exist and/or contribute your own example.\n" | ||
) | ||
index_file.write(categories["other"]["table"]) | ||
|
||
_add_all_entries(index_file) | ||
|
||
index_file.write( | ||
"\n.. toctree::\n :maxdepth: 1\n :caption: Quickstart\n :hidden:\n\n" | ||
) | ||
index_file.write(categories["quickstart"]["list"]) | ||
|
||
index_file.write( | ||
"\n.. toctree::\n :maxdepth: 1\n :caption: Advanced\n :hidden:\n\n" | ||
) | ||
index_file.write(categories["advanced"]["list"]) | ||
|
||
index_file.write( | ||
"\n.. toctree::\n :maxdepth: 1\n :caption: Others\n :hidden:\n\n" | ||
) | ||
index_file.write(categories["other"]["list"]) | ||
|
||
index_file.write("\n") | ||
|
||
|
||
if __name__ == "__main__": | ||
_main() | ||
subprocess.call(f"cd {ROOT}/examples/doc && make html", shell=True) |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we add a link to the "contribute your own example" text pointing to our contributors guide?