diff --git a/.github/workflows/docs-test.yml b/.github/workflows/docs-test.yml new file mode 100644 index 00000000..76cf5218 --- /dev/null +++ b/.github/workflows/docs-test.yml @@ -0,0 +1,38 @@ +name: Test Documentation Build + +on: + pull_request: + branches: + - main + +permissions: + contents: read + +jobs: + test-build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + with: + python-version: '3.11' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install mkdocs-material + pip install mkdocstrings[python] + pip install mkdocs-include-markdown-plugin + - name: Install package + run: pip install -e . + - name: Build site + run: mkdocs build + env: + PYTHONPATH: ${{ github.workspace }} + - name: Verify build output + run: | + if [ ! -d "site" ]; then + echo "Documentation build failed - site directory not created" + exit 1 + fi + echo "Documentation build successful - site directory created and contains:" + ls -la site/ diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml new file mode 100644 index 00000000..43815e2c --- /dev/null +++ b/.github/workflows/github-pages.yml @@ -0,0 +1,61 @@ +name: Deploy GitHub Pages + +on: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + with: + python-version: '3.11' + - uses: actions/configure-pages@v4 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install mkdocs-material + pip install mkdocstrings[python] + pip install mkdocs-include-markdown-plugin + - name: Install package + run: pip install -e . + - name: Build site + run: mkdocs build + env: + PYTHONPATH: ${{ github.workspace }} + - name: Verify build output + run: | + if [ ! -d "site" ]; then + echo "Documentation build failed - site directory not created" + exit 1 + fi + echo "Documentation build successful - site directory created and contains:" + ls -la site/ + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: site + + deploy: + needs: build + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/README.md b/README.md index 389dae28..bf9f5ed2 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,43 @@ yes 'third_party' | autonomy packages lock ``` +## Documentation + +For detailed information about using auto_dev, check out our documentation: + +You can access our documentation in two ways: +- Online at [GitHub Pages](https://8ball030.github.io/auto_dev/) +- Or through the following markdown files: + - [Installation Guide](docs/installation.md) - Complete setup instructions and environment configuration + - [Usage Guide](docs/usage.md) - Detailed examples and common workflows + - [CLI Reference](docs/commands/index.md) - Comprehensive command-line interface documentation + - [Deployment Guide](docs/deployment.md) - Instructions for local and production deployments + +For development setup and contribution guidelines, see the [Installation Guide](docs/installation.md#development-setup). + +### Local Documentation + +To run the documentation locally: +1. Follow the [documentation setup guide](docs/installation.md#running-documentation-locally) +2. Visit `http://127.0.0.1:8000/` in your browser +3. Documentation will auto-reload as you make changes + +## Development + +For development tools and workflows: +- [Code Formatting](docs/usage.md#development-workflow) - Learn about code formatting standards +- [Testing](docs/usage.md#development-workflow) - Running and writing tests +- [Contributing](docs/contributing.md) - Guidelines for contributing +- [Deployment](docs/deployment.md) - Setting up development environments + +## Usage Examples + +Check out these guides for common use cases: +- [Quick Start](docs/usage.md#quick-start-guide) - Get started quickly +- [Protocol Scaffolding](docs/usage.md#common-workflows) - Generate protocol components +- [Contract Integration](docs/usage.md#common-workflows) - Work with smart contracts +- [Development Tools](docs/installation.md#development-tools) - Available development tools + ```bash # run the agent and verify the endpoint diff --git a/auto_dev/commands/deps.py b/auto_dev/commands/deps.py index 0508e9f4..39b093b9 100644 --- a/auto_dev/commands/deps.py +++ b/auto_dev/commands/deps.py @@ -45,7 +45,7 @@ from rich.progress import track from auto_dev.base import build_cli -from auto_dev.utils import FileLoader, write_to_file, FileType +from auto_dev.utils import FileType, FileLoader, write_to_file from auto_dev.constants import DEFAULT_TIMEOUT, DEFAULT_ENCODING from auto_dev.exceptions import AuthenticationError, NetworkTimeoutError diff --git a/auto_dev/commands/repo.py b/auto_dev/commands/repo.py index a01fc94e..6b177241 100644 --- a/auto_dev/commands/repo.py +++ b/auto_dev/commands/repo.py @@ -185,13 +185,7 @@ def repo() -> None: @repo.command() @click.argument("name", type=str, required=True) -@click.option( - "-t", - "--type-of-repo", - help="Type of repo to scaffold", - type=click.Choice(TEMPLATES), - default="autonomy" -) +@click.option("-t", "--type-of-repo", help="Type of repo to scaffold", type=click.Choice(TEMPLATES), default="autonomy") @click.option("-f", "--force", is_flag=True, help="Force overwrite of existing repo", default=False) @click.option("--auto-approve", is_flag=True, help="Automatically approve all prompts", default=False) @click.option("--install/--no-install", is_flag=True, help="Do not install dependencies", default=True) @@ -230,11 +224,7 @@ def scaffold(ctx, name, type_of_repo, force, auto_approve, install, initial_comm execute_commands("bash ./install.sh", verbose=verbose, logger=logger) if initial_commit: - git_commands = [ - "git init", - "git add .", - "git commit -m 'feat-first-commit-from-StationsStation'" - ] + git_commands = ["git init", "git add .", "git commit -m 'feat-first-commit-from-StationsStation'"] execute_commands(*git_commands, verbose=verbose, logger=logger) logger.info("Initialising autonomy packages.") @@ -252,7 +242,6 @@ def scaffold(ctx, name, type_of_repo, force, auto_approve, install, initial_comm logger.info(f"{type_of_repo.capitalize()} successfully setup.") - @dataclass(frozen=True) class AutonomyVersionSet: """Class to represent a set of autonomy versions.""" diff --git a/auto_dev/dao/dummy_data.py b/auto_dev/dao/dummy_data.py index 2a5265b3..dfaaac24 100644 --- a/auto_dev/dao/dummy_data.py +++ b/auto_dev/dao/dummy_data.py @@ -52,10 +52,7 @@ def _generate_model_dummy_data(model_schema: dict[str, Any]) -> dict[str, Any]: dummy_instance = {} for prop_name, prop_schema in properties.items(): if prop_schema.get("type") == "array": - dummy_instance[prop_name] = [ - _generate_property_dummy_data(prop_schema["items"]) - for _ in range(3) - ] + dummy_instance[prop_name] = [_generate_property_dummy_data(prop_schema["items"]) for _ in range(3)] else: dummy_instance[prop_name] = _generate_property_dummy_data(prop_schema) return dummy_instance diff --git a/auto_dev/dao/scaffolder.py b/auto_dev/dao/scaffolder.py index c35ec47d..dd377193 100644 --- a/auto_dev/dao/scaffolder.py +++ b/auto_dev/dao/scaffolder.py @@ -240,9 +240,7 @@ def _generate_and_save_init_file(self, dao_classes: dict[str, str]) -> None: file_names = [camel_to_snake(model) for model in model_names] model_file_pairs = list(zip(model_names, file_names, strict=False)) init_template = self.env.get_template("__init__.jinja") - init_content = init_template.render( - model_file_pairs=model_file_pairs - ) + init_content = init_template.render(model_file_pairs=model_file_pairs) dao_dir = Path("daos") init_file_path = dao_dir / "__init__.py" write_to_file(init_file_path, init_content, FileType.PYTHON) @@ -258,11 +256,7 @@ def identify_persistent_schemas(self, api_spec: dict[str, Any]) -> list[str]: self._analyze_paths(api_spec, schema_usage, schemas) - return [ - schema - for schema, usage in schema_usage.items() - if "response" in usage or "nested_request" in usage - ] + return [schema for schema, usage in schema_usage.items() if "response" in usage or "nested_request" in usage] def _analyze_paths(self, api_spec: dict[str, Any], schema_usage: dict[str, set], schemas: dict[str, Any]) -> None: for path_details in api_spec.get("paths", {}).values(): @@ -270,10 +264,7 @@ def _analyze_paths(self, api_spec: dict[str, Any], schema_usage: dict[str, set], self._analyze_method(method_details, schema_usage, schemas) def _analyze_method( - self, - method_details: dict[str, Any], - schema_usage: dict[str, set], - schemas: dict[str, Any] + self, method_details: dict[str, Any], schema_usage: dict[str, set], schemas: dict[str, Any] ) -> None: if "requestBody" in method_details: self._analyze_content(method_details["requestBody"].get("content", {}), "request", schema_usage, schemas) @@ -282,11 +273,7 @@ def _analyze_method( self._analyze_content(response_details.get("content", {}), "response", schema_usage, schemas) def _analyze_content( - self, - content: dict[str, Any], - usage_type: str, - schema_usage: dict[str, set], - schemas: dict[str, Any] + self, content: dict[str, Any], usage_type: str, schema_usage: dict[str, set], schemas: dict[str, Any] ) -> None: for media_details in content.values(): schema = media_details.get("schema", {}) @@ -296,11 +283,7 @@ def _analyze_content( self._analyze_schema(schema, usage_type, schema_usage, schemas) def _analyze_schema( - self, - schema: dict[str, Any], - usage_type: str, - schema_usage: dict[str, set], - schemas: dict[str, Any] + self, schema: dict[str, Any], usage_type: str, schema_usage: dict[str, set], schemas: dict[str, Any] ) -> None: schema_name = self._process_schema(schema) if schema_name: @@ -308,11 +291,7 @@ def _analyze_schema( self._analyze_nested_properties(schema_name, usage_type, schema_usage, schemas) def _analyze_nested_properties( - self, - schema_name: str, - usage_type: str, - schema_usage: dict[str, set], - schemas: dict[str, Any] + self, schema_name: str, usage_type: str, schema_usage: dict[str, set], schemas: dict[str, Any] ) -> None: if "properties" in schemas.get(schema_name, {}): for prop in schemas[schema_name].get("properties", {}).values(): diff --git a/auto_dev/handler/scaffolder.py b/auto_dev/handler/scaffolder.py index 043877f5..17a1e466 100644 --- a/auto_dev/handler/scaffolder.py +++ b/auto_dev/handler/scaffolder.py @@ -94,11 +94,7 @@ def extract_schema(self, operation, persistent_schemas): return None success_response = next( - ( - operation["responses"].get(code, {}) - for code in ["201", "200"] - if code in operation["responses"] - ), + (operation["responses"].get(code, {}) for code in ["201", "200"] if code in operation["responses"]), {}, ) content = success_response.get("content", {}).get("application/json", {}) @@ -151,9 +147,7 @@ def generate_handler(self) -> None: raise SystemExit(1) self.handler_code = self._generate_handler_code( - persistent_schemas, - "\n\n".join(handler_methods), - self._get_path_params(openapi_spec) + persistent_schemas, "\n\n".join(handler_methods), self._get_path_params(openapi_spec) ) if not self.handler_code: @@ -164,9 +158,7 @@ def generate_handler(self) -> None: def _get_persistent_schemas(self, openapi_spec): schemas = openapi_spec.get("components", {}).get("schemas", {}) - persistent_schemas = [ - schema for schema, details in schemas.items() if details.get("x-persistent") - ] + persistent_schemas = [schema for schema, details in schemas.items() if details.get("x-persistent")] return persistent_schemas or self.identify_persistent_schemas(openapi_spec) def _confirm_schemas(self, persistent_schemas): @@ -180,24 +172,30 @@ def _generate_handler_methods(self, openapi_spec, persistent_schemas): for path, path_item in openapi_spec["paths"].items(): for method, operation in path_item.items(): method_name = self.generate_method_name(method, path) - path_params = [param.strip("{}") for param in path.split("/") if param.startswith("{") and param.endswith("}")] + path_params = [ + param.strip("{}") for param in path.split("/") if param.startswith("{") and param.endswith("}") + ] path_params_snake_case = [camel_to_snake(param) for param in path_params] schema = self.extract_schema(operation, persistent_schemas) operation_type = "other" if method.lower() != "post" else self.classify_post_operation(path, operation) # Extract response information response_info = self._extract_response_info(operation) - + # Extract error responses error_responses = self._extract_error_responses(operation) method_code = self.jinja_env.get_template("method_template.jinja").render( - method_name=method_name, method=method, path=path, - path_params=path_params, path_params_snake_case=path_params_snake_case, - schema=schema, operation_type=operation_type, - status_code=response_info['status_code'], - status_text=response_info['status_text'], - headers=response_info['headers'], + method_name=method_name, + method=method, + path=path, + path_params=path_params, + path_params_snake_case=path_params_snake_case, + schema=schema, + operation_type=operation_type, + status_code=response_info["status_code"], + status_text=response_info["status_text"], + headers=response_info["headers"], error_responses=error_responses, ) handler_methods.append(method_code) @@ -402,10 +400,7 @@ def process_schema(schema: dict[str, Any], usage_type: str) -> None: for content in response.get("content", {}).values(): process_schema(content.get("schema", {}), "response") - return [ - schema for schema, usage in schema_usage.items() - if "response" in usage or "nested_request" in usage - ] + return [schema for schema, usage in schema_usage.items() if "response" in usage or "nested_request" in usage] def _extract_response_info(self, operation): responses = operation.get("responses", {}) diff --git a/auto_dev/utils.py b/auto_dev/utils.py index 9fb0d797..a281d2ef 100644 --- a/auto_dev/utils.py +++ b/auto_dev/utils.py @@ -301,9 +301,7 @@ def write_to_file(file_path: str, content: Any, file_type: FileType = FileType.T f.write(content) elif file_type is FileType.YAML: if isinstance(content, list): - yaml.dump_all(content, f, - default_flow_style=False, - sort_keys=False) + yaml.dump_all(content, f, default_flow_style=False, sort_keys=False) else: yaml.dump(content, f, default_flow_style=False, sort_keys=False) elif file_type is FileType.JSON: diff --git a/docs/api/commands.md b/docs/api/commands.md deleted file mode 100644 index 04ba2a51..00000000 --- a/docs/api/commands.md +++ /dev/null @@ -1,3 +0,0 @@ -# Connections - -::: connections \ No newline at end of file diff --git a/docs/api/index.md b/docs/api/index.md index 754ccd44..568d6bad 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -5,11 +5,11 @@ This section provides detailed information about the auto_dev API. Use the navig ## Main Modules - [auto_dev](auto_dev.md): Core functionality -- [Commands](commands.md): CLI commands +- [Commands](../commands/index.md): CLI commands - [Connections](connections.md): Network connections - [Contracts](contracts.md): Smart contract interactions - [FSM](fsm.md): Finite State Machine implementation - [Handler](handler.md): Request handling - [Protocols](protocols.md): Communication protocols - [Utils](utils.md): Utility functions -- [Constants](constants.md): Constant values used across the project \ No newline at end of file +- [Constants](constants.md): Constant values used across the project diff --git a/docs/changelog.md b/docs/changelog.md index 67259dad..07433eb7 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,3 +1,9 @@ -{% - include-markdown "../CHANGELOG.md" -%} +--- +title: Changelog +--- + +# Changelog + +## 0.1.0 (2022-08-20) + +* First release on PyPI. diff --git a/docs/commands/index.md b/docs/commands/index.md new file mode 100644 index 00000000..5a3be1a7 --- /dev/null +++ b/docs/commands/index.md @@ -0,0 +1,341 @@ +# CLI Commands Reference + +This page provides a comprehensive reference for all available CLI commands in auto_dev. + +## Core Commands + +### create +Create a new agent from a template. + +```bash +adev create -t