Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit 865b093

Browse files
prefect-collection-synchronizer[bot]desertaxleahuang11ahuang11
authored
Sync Collection with changes to prefect-collection-template (#204)
Co-authored-by: desertaxle <[email protected]> Co-authored-by: ahuang11 <[email protected]> Co-authored-by: Andrew <[email protected]>
1 parent 6b2ce3b commit 865b093

15 files changed

+356
-116
lines changed

.cruft.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"template": "https://github.com/PrefectHQ/prefect-collection-template",
3-
"commit": "9495ca71f74c279e9d9beff90f1d9f53f77637aa",
3+
"commit": "e11a3be195f24f60ed3f564dfccb40170ee7c3fa",
44
"checkout": null,
55
"context": {
66
"cookiecutter": {
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Nightly tests against Prefect's main branch
2+
on:
3+
schedule:
4+
- cron: "0 6 * * *"
5+
workflow_dispatch:
6+
7+
jobs:
8+
submit-update-pr:
9+
name: Run tests against Prefect's main branch
10+
runs-on: ubuntu-latest
11+
strategy:
12+
matrix:
13+
python-version:
14+
- "3.7"
15+
- "3.8"
16+
- "3.9"
17+
- "3.10"
18+
fail-fast: false
19+
steps:
20+
- uses: actions/checkout@v3
21+
22+
- name: Set up Python ${{ matrix.python-version }}
23+
uses: actions/setup-python@v4
24+
with:
25+
python-version: ${{ matrix.python-version }}
26+
cache: pip
27+
cache-dependency-path: requirements*.txt
28+
29+
- name: Install dependencies
30+
run: |
31+
python -m pip install --upgrade pip
32+
python -m pip install --upgrade --upgrade-strategy eager -e ".[dev]" "prefect @ git+https://github.com/PrefectHQ/prefect.git@main"
33+
34+
- name: Run tests
35+
env:
36+
PREFECT_API_DATABASE_CONNECTION_URL: "sqlite+aiosqlite:///./collection-tests.db"
37+
run: |
38+
pytest tests -vv

.github/workflows/template-sync.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: Template Synchronization
22
on:
33
schedule:
4-
- cron: "0 0 * * *"
4+
- cron: "0 6 * * *"
55
workflow_dispatch:
66

77
jobs:

.github/workflows/tests.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ jobs:
3131
3232
- name: Run tests
3333
env:
34-
PREFECT_ORION_DATABASE_CONNECTION_URL: "sqlite+aiosqlite:///./orion-tests.db"
34+
PREFECT_SERVER_DATABASE_CONNECTION_URL: "sqlite+aiosqlite:///./collection-tests.db"
3535
run: |
36-
prefect orion database reset -y
36+
prefect server database reset -y
3737
coverage run --branch -m pytest tests -vv
3838
coverage report
3939

.github/workflows/windows-tests.yml

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
name: Windows Tests
3+
4+
on: [pull_request]
5+
6+
jobs:
7+
run-tests:
8+
name: Run Tests
9+
runs-on: windows-latest
10+
strategy:
11+
matrix:
12+
# Prefect only tests 3.9 on Windows
13+
python-version:
14+
- "3.9"
15+
fail-fast: false
16+
steps:
17+
- uses: actions/checkout@v3
18+
19+
- name: Set up Python ${{ matrix.python-version }}
20+
uses: actions/setup-python@v4
21+
with:
22+
python-version: ${{ matrix.python-version }}
23+
cache: pip
24+
cache-dependency-path: requirements*.txt
25+
26+
- name: Install dependencies
27+
run: |
28+
python -m pip install --upgrade pip
29+
python -m pip install --upgrade --upgrade-strategy eager -e ".[dev]"
30+
- name: Run tests
31+
env:
32+
PREFECT_SERVER_DATABASE_CONNECTION_URL: "sqlite+aiosqlite:///./collection-tests.db"
33+
run: |
34+
pytest tests -vv

MAINTAINERS.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ To verify the setup was successful you can run the following:
6666

6767
## Developing tasks and flows
6868

69-
For information about the use and development of tasks and flow, check out the [flows](https://orion-docs.prefect.io/concepts/flows/) and [tasks](https://orion-docs.prefect.io/concepts/tasks/) concepts docs in the Prefect docs.
69+
For information about the use and development of tasks and flow, check out the [flows](https://docs.prefect.io/concepts/flows/) and [tasks](https://docs.prefect.io/concepts/tasks/) concepts docs in the Prefect docs.
7070

7171
## Writing documentation
7272

@@ -98,7 +98,7 @@ To publish a new version of your collection, [create a new GitHub release](https
9898

9999
Upon publishing, a `docs` branch is automatically created. To hook this up to GitHub Pages, simply head over to https://github.com/PrefectHQ/prefect-aws/settings/pages, select `docs` under the dropdown menu, keep the default `/root` folder, `Save`, and upon refresh, you should see a prompt stating "Your site is published at https://PrefectHQ.github.io/prefect-aws". Don't forget to add this link to the repo's "About" section, under "Website" so users can access the docs easily.
100100

101-
Feel free to [submit your collection](https://orion-docs.prefect.io/collections/overview/#listing-in-the-collections-catalog) to the Prefect [Collections Catalog](https://orion-docs.prefect.io/collections/catalog/)!
101+
Feel free to [submit your collection](https://docs.prefect.io/collections/overview/#listing-in-the-collections-catalog) to the Prefect [Collections Catalog](https://docs.prefect.io/collections/catalog/)!
102102

103103
## Further guidance
104104

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ custom_example_flow = example_flow.with_options(
9999

100100
Refer to the API documentation on the sidebar to explore all the capabilities of Prefect AWS!
101101

102-
For more tips on how to use tasks and flows in a Collection, check out [Using Collections](https://orion-docs.prefect.io/collections/usage/)!
102+
For more tips on how to use tasks and flows in a Collection, check out [Using Collections](https://docs.prefect.io/collections/usage/)!
103103

104104
### Recipes
105105

@@ -127,7 +127,7 @@ Requires an installation of Python 3.7+
127127

128128
We recommend using a Python virtual environment manager such as pipenv, conda or virtualenv.
129129

130-
These tasks are designed to work with Prefect 2.0. For more information about how to use Prefect, please refer to the [Prefect documentation](https://orion-docs.prefect.io/).
130+
These tasks are designed to work with Prefect 2.0. For more information about how to use Prefect, please refer to the [Prefect documentation](https://docs.prefect.io/).
131131

132132
### Contributing
133133

docs/gen_blocks_catalog.py

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
"""
2+
Discovers all blocks and generates a list of them in the docs
3+
under the Blocks Catalog heading.
4+
"""
5+
6+
from pathlib import Path
7+
from textwrap import dedent
8+
9+
import mkdocs_gen_files
10+
from prefect.blocks.core import Block
11+
from prefect.utilities.dispatch import get_registry_for_type
12+
from prefect.utilities.importtools import from_qualified_name, to_qualified_name
13+
14+
COLLECTION_SLUG = "prefect_aws"
15+
16+
17+
def find_module_blocks():
18+
blocks = get_registry_for_type(Block)
19+
collection_blocks = [
20+
block
21+
for block in blocks.values()
22+
if to_qualified_name(block).startswith(COLLECTION_SLUG)
23+
]
24+
module_blocks = {}
25+
for block in collection_blocks:
26+
block_name = block.__name__
27+
module_nesting = tuple(to_qualified_name(block).split(".")[1:-1])
28+
if module_nesting not in module_blocks:
29+
module_blocks[module_nesting] = []
30+
module_blocks[module_nesting].append(block_name)
31+
return module_blocks
32+
33+
34+
def insert_blocks_catalog(generated_file):
35+
module_blocks = find_module_blocks()
36+
if len(module_blocks) == 0:
37+
return
38+
generated_file.write(
39+
dedent(
40+
f"""
41+
Below is a list of Blocks available for registration in
42+
`prefect-aws`.
43+
44+
To register blocks in this module to
45+
[view and edit them](https://docs.prefect.io/ui/blocks/)
46+
on Prefect Cloud, first [install the required packages](
47+
https://PrefectHQ.github.io/prefect-aws/#installation),
48+
then
49+
```bash
50+
prefect block register -m {COLLECTION_SLUG}
51+
```
52+
""" # noqa
53+
)
54+
)
55+
generated_file.write(
56+
"Note, to use the `load` method on Blocks, you must already have a block document " # noqa
57+
"[saved through code](https://docs.prefect.io/concepts/blocks/#saving-blocks) " # noqa
58+
"or [saved through the UI](https://docs.prefect.io/ui/blocks/).\n"
59+
)
60+
for module_nesting, block_names in module_blocks.items():
61+
module_path = f"{COLLECTION_SLUG}." + " ".join(module_nesting)
62+
module_title = (
63+
module_path.replace(COLLECTION_SLUG, "")
64+
.lstrip(".")
65+
.replace("_", " ")
66+
.title()
67+
)
68+
generated_file.write(f"## [{module_title} Module][{module_path}]\n")
69+
for block_name in block_names:
70+
block_obj = from_qualified_name(f"{module_path}.{block_name}")
71+
block_description = block_obj.get_description()
72+
if not block_description.endswith("."):
73+
block_description += "."
74+
generated_file.write(
75+
f"[{block_name}][{module_path}.{block_name}]\n\n{block_description}\n\n"
76+
)
77+
generated_file.write(
78+
dedent(
79+
f"""
80+
To load the {block_name}:
81+
```python
82+
from prefect import flow
83+
from {module_path} import {block_name}
84+
85+
@flow
86+
def my_flow():
87+
my_block = {block_name}.load("MY_BLOCK_NAME")
88+
89+
my_flow()
90+
```
91+
"""
92+
)
93+
)
94+
generated_file.write(
95+
f"For additional examples, check out the [{module_title} Module]"
96+
f"(../examples_catalog/#{module_nesting[-1]}-module) "
97+
f"under Examples Catalog.\n"
98+
)
99+
100+
101+
blocks_catalog_path = Path("blocks_catalog.md")
102+
with mkdocs_gen_files.open(blocks_catalog_path, "w") as generated_file:
103+
insert_blocks_catalog(generated_file)

docs/gen_examples_catalog.py

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
"""
2+
Locates all the examples in the Collection and puts them in a single page.
3+
"""
4+
5+
import re
6+
from collections import defaultdict
7+
from inspect import getmembers, isclass, isfunction
8+
from pathlib import Path
9+
from pkgutil import iter_modules
10+
from textwrap import dedent
11+
from types import ModuleType
12+
from typing import Callable, Set, Union
13+
14+
import mkdocs_gen_files
15+
from griffe.dataclasses import Docstring
16+
from griffe.docstrings.dataclasses import DocstringSectionKind
17+
from griffe.docstrings.parsers import Parser, parse
18+
from prefect.logging.loggers import disable_logger
19+
from prefect.utilities.importtools import load_module, to_qualified_name
20+
21+
import prefect_aws
22+
23+
COLLECTION_SLUG = "prefect_aws"
24+
25+
26+
def skip_parsing(name: str, obj: Union[ModuleType, Callable], module_nesting: str):
27+
"""
28+
Skips parsing the object if it's a private object or if it's not in the
29+
module nesting, preventing imports from other libraries from being added to the
30+
examples catalog.
31+
"""
32+
try:
33+
wrong_module = not to_qualified_name(obj).startswith(module_nesting)
34+
except AttributeError:
35+
wrong_module = False
36+
return obj.__doc__ is None or name.startswith("_") or wrong_module
37+
38+
39+
def skip_block_load_code_example(code_example: str) -> bool:
40+
"""
41+
Skips the code example if it's just showing how to load a Block.
42+
"""
43+
return re.search(r'\.load\("BLOCK_NAME"\)\s*$', code_example.rstrip("`"))
44+
45+
46+
def get_code_examples(obj: Union[ModuleType, Callable]) -> Set[str]:
47+
"""
48+
Gathers all the code examples within an object.
49+
"""
50+
code_examples = set()
51+
with disable_logger("griffe.docstrings.google"):
52+
with disable_logger("griffe.agents.nodes"):
53+
docstring = Docstring(obj.__doc__)
54+
parsed_sections = parse(docstring, Parser.google)
55+
56+
for section in parsed_sections:
57+
if section.kind == DocstringSectionKind.examples:
58+
code_example = "\n".join(
59+
(part[1] for part in section.as_dict().get("value", []))
60+
)
61+
if not skip_block_load_code_example(code_example):
62+
code_examples.add(code_example)
63+
if section.kind == DocstringSectionKind.admonition:
64+
value = section.as_dict().get("value", {})
65+
if value.get("annotation") == "example":
66+
code_example = value.get("description")
67+
if not skip_block_load_code_example(code_example):
68+
code_examples.add(code_example)
69+
70+
return code_examples
71+
72+
73+
code_examples_grouping = defaultdict(set)
74+
for _, module_name, ispkg in iter_modules(prefect_aws.__path__):
75+
76+
module_nesting = f"{COLLECTION_SLUG}.{module_name}"
77+
module_obj = load_module(module_nesting)
78+
79+
# find all module examples
80+
if skip_parsing(module_name, module_obj, module_nesting):
81+
continue
82+
code_examples_grouping[module_name] |= get_code_examples(module_obj)
83+
84+
# find all class and method examples
85+
for class_name, class_obj in getmembers(module_obj, isclass):
86+
if skip_parsing(class_name, class_obj, module_nesting):
87+
continue
88+
code_examples_grouping[module_name] |= get_code_examples(class_obj)
89+
for method_name, method_obj in getmembers(class_obj, isfunction):
90+
if skip_parsing(method_name, method_obj, module_nesting):
91+
continue
92+
code_examples_grouping[module_name] |= get_code_examples(method_obj)
93+
94+
# find all function examples
95+
for function_name, function_obj in getmembers(module_obj, callable):
96+
if skip_parsing(function_name, function_obj, module_nesting):
97+
continue
98+
code_examples_grouping[module_name] |= get_code_examples(function_obj)
99+
100+
101+
examples_catalog_path = Path("examples_catalog.md")
102+
with mkdocs_gen_files.open(examples_catalog_path, "w") as generated_file:
103+
generated_file.write(
104+
dedent(
105+
"""
106+
# Examples Catalog
107+
108+
Below is a list of examples for `prefect-aws`.
109+
"""
110+
)
111+
)
112+
for module_name, code_examples in code_examples_grouping.items():
113+
if len(code_examples) == 0:
114+
continue
115+
module_title = module_name.replace("_", " ").title()
116+
generated_file.write(
117+
f"## [{module_title} Module][{COLLECTION_SLUG}.{module_name}]\n"
118+
)
119+
for code_example in code_examples:
120+
generated_file.write(code_example + "\n")

docs/gen_home_page.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"""
2+
Copies README.md to index.md.
3+
"""
4+
5+
from pathlib import Path
6+
7+
import mkdocs_gen_files
8+
9+
# Home page
10+
11+
readme_path = Path("README.md")
12+
docs_index_path = Path("index.md")
13+
14+
with open(readme_path, "r") as readme:
15+
with mkdocs_gen_files.open(docs_index_path, "w") as generated_file:
16+
for line in readme:
17+
if line.startswith("Visit the full docs [here]("):
18+
continue # prevent linking to itself
19+
generated_file.write(line)
20+
21+
mkdocs_gen_files.set_edit_path(Path(docs_index_path), readme_path)

0 commit comments

Comments
 (0)