fabricatio


Namefabricatio JSON
Version 0.2.1 PyPI version JSON
download
home_pageNone
SummaryA LLM multi-agent framework.
upload_time2025-02-21 11:56:24
maintainerNone
docs_urlNone
authorNone
requires_python>=3.12
licenseNone
keywords ai agents multi-agent llm pyo3
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            
# Fabricatio

![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)
![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)
![Build Status](https://img.shields.io/badge/build-passing-brightgreen)

Fabricatio is a Python library designed for building LLM (Large Language Model) applications using an event-based agent structure. It integrates Rust for performance-critical tasks, utilizes Handlebars for templating, and employs PyO3 for Python bindings.

## Features

- **Event-Based Architecture**: Utilizes an EventEmitter pattern for robust task management.
- **LLM Integration**: Supports interactions with large language models for intelligent task processing.
- **Templating Engine**: Uses Handlebars for dynamic content generation.
- **Toolboxes**: Provides predefined toolboxes for common operations like file manipulation and arithmetic.
- **Async Support**: Fully asynchronous for efficient execution.
- **Extensible**: Easy to extend with custom actions, workflows, and tools.

## Installation

### Using UV (Recommended)

To install Fabricatio using `uv` (a package manager for Python):

```bash
# Install uv if not already installed
pip install uv

# Clone the repository
git clone https://github.com/Whth/fabricatio.git
cd fabricatio

# Install the package in development mode with uv
uv --with-editable . maturin develop --uv -r
```

### Building Distribution

For production builds:

```bash
# Build distribution packages
make bdist
```

This will generate distribution files in the `dist` directory.

## Usage

### Basic Example

Below are some basic examples demonstrating how to use Fabricatio for different purposes.

#### Simple Hello World Program

```python
import asyncio
from fabricatio import Action, Role, Task, logger


class Hello(Action):
    """Action that says hello."""

    name: str = "hello"
    output_key: str = "task_output"

    async def _execute(self, task_input: Task[str], **_) -> Any:
        ret = "Hello fabricatio!"
        logger.info("executing talk action")
        return ret


async def main() -> None:
    """Main function."""
    role = Role(
        name="talker", 
        description="talker role", 
        registry={Task.pending_label: WorkFlow(name="talk", steps=(Hello,))}
    )

    task = Task(name="say hello", goal="say hello", description="say hello to the world")
    result = await task.delegate()
    logger.success(f"Result: {result}")


if __name__ == "__main__":
    asyncio.run(main())
```

#### Writing and Dumping Code

```python
import asyncio
from fabricatio import Action, Event, PythonCapture, Role, Task, ToolBox, WorkFlow, fs_toolbox, logger


class WriteCode(Action):
    """Action that writes code based on a prompt."""

    name: str = "write code"
    output_key: str = "source_code"

    async def _execute(self, task_input: Task[str], **_) -> str:
        return await self.aask_validate(
            task_input.briefing,
            validator=PythonCapture.capture,
        )


class DumpCode(Action):
    """Action that dumps code to the file system."""

    name: str = "dump code"
    description: str = "Dump code to file system"
    toolboxes: set[ToolBox] = {fs_toolbox}
    output_key: str = "task_output"

    async def _execute(self, task_input: Task, source_code: str, **_) -> Any:
        path = await self.handle_fin_grind(task_input, {"source_code": source_code})
        return path[0] if path else None


async def main() -> None:
    """Main function."""
    role = Role(
        name="Coder",
        description="A python coder who can write and document code",
        registry={
            Event.instantiate_from("coding.*").push("pending"): WorkFlow(
                name="write code", steps=(WriteCode, DumpCode)
            ),
        },
    )

    prompt = "write a Python CLI app which prints 'hello world' n times with detailed Google-style docstring. Write the source code to `cli.py`."

    proposed_task = await role.propose(prompt)
    path = await proposed_task.move_to("coding").delegate()
    logger.success(f"Code Path: {path}")


if __name__ == "__main__":
    asyncio.run(main())
```

#### Proposing Tasks

```python
import asyncio
from typing import Any

from fabricatio import Action, Role, Task, WorkFlow, logger


class WriteDocumentation(Action):
    """Action that generates documentation for the code in markdown format."""

    name: str = "write documentation"
    description: str = "Write detailed documentation for the provided code."
    output_key: str = "task_output"

    async def _execute(self, task_input: Task[str], **_) -> str:
        return await self.aask(task_input.briefing)


async def main() -> None:
    """Main function."""
    role = Role(
        name="Documenter",
        description="Role responsible for writing documentation.",
        registry={
            "doc.*": WorkFlow(name="write documentation", steps=(WriteDocumentation,))
        }
    )

    prompt = "write a Rust clap CLI that downloads an HTML page"
    proposed_task = await role.propose(prompt)
    documentation = await proposed_task.move_to("doc").delegate()
    logger.success(f"Documentation:\n{documentation}")


if __name__ == "__main__":
    asyncio.run(main())
```

#### Complex Workflow Handling

```python
import asyncio
from fabricatio import Action, Event, Role, Task, WorkFlow, logger


class WriteCode(Action):
    """Action that writes code based on a prompt."""

    name: str = "write code"
    output_key: str = "source_code"

    async def _execute(self, task_input: Task[str], **_) -> str:
        return await self.aask_validate(
            task_input.briefing,
            validator=PythonCapture.capture,
        )


class WriteDocumentation(Action):
    """Action that generates documentation for the code in markdown format."""

    name: str = "write documentation"
    description: str = "Write detailed documentation for the provided code."
    output_key: str = "task_output"

    async def _execute(self, task_input: Task[str], **_) -> str:
        return await self.aask(task_input.briefing)


async def main() -> None:
    """Main function."""
    role = Role(
        name="Developer",
        description="A developer who can write code and documentation.",
        registry={
            Event.instantiate_from("coding.*").push("pending"): WorkFlow(
                name="write code", steps=(WriteCode,)
            ),
            Event.instantiate_from("doc.*").push("pending"): WorkFlow(
                name="write documentation", steps=(WriteDocumentation,)
            ),
        }
    )

    # Propose a coding task
    code_task_prompt = "write a Python CLI app which adds numbers from a file."
    proposed_task = await role.propose(code_task_prompt)
    code = await proposed_task.move_to("coding").delegate()
    logger.success(f"Code:\n{code}")

    # Propose a documentation task
    doc_task_prompt = f"{code}\n\nwrite Readme.md file for the above code."
    proposed_doc_task = await role.propose(doc_task_prompt)
    documentation = await proposed_doc_task.move_to("doc").delegate()
    logger.success(f"Documentation:\n{documentation}")


if __name__ == "__main__":
    asyncio.run(main())
```

### Advanced Examples

#### Template Management and Rendering

```python
from fabricatio._rust_instances import template_manager

template_name = "claude-xml.hbs"
data = {
    "absolute_code_path": "/path/to/project",
    "source_tree": "source tree content",
    "files": [{"path": "file1.py", "code": "print('Hello')"}],
}

rendered_template = template_manager.render_template(template_name, data)
print(rendered_template)
```

#### Handling Security Vulnerabilities

```python
from fabricatio.models.usages import ToolBoxUsage
from fabricatio.models.task import Task

toolbox_usage = ToolBoxUsage()

async def handle_security_vulnerabilities():
    task = Task(
        name="Security Check",
        goal=["Identify security vulnerabilities"],
        description="Perform a thorough security review on the project.",
        dependencies=["./src/main.py"]
    )
    
    vulnerabilities = await toolbox_usage.gather_tools_fine_grind(task)
    for vulnerability in vulnerabilities:
        print(f"Found vulnerability: {vulnerability.name}")
```

#### Managing CTF Challenges

```python
import asyncio

from fabricatio.models.usages import ToolBoxUsage
from fabricatio.models.task import Task

toolbox_usage = ToolBoxUsage()

async def solve_ctf_challenge(challenge_name: str, challenge_description: str, files: list[str]):
    task = Task(
        name=challenge_name,
        goal=[f"Solve {challenge_name} challenge"],
        description=challenge_description,
        dependencies=files
    )
    
    solution = await toolbox_usage.gather_tools_fine_grind(task)
    print(f"Challenge Solved: {solution}")

if __name__ == "__main__":
    asyncio.run(solve_ctf_challenge("Binary Exploitation", "CTF Binary Exploitation Challenge", ["./challenges/binary_exploit"]))
```

### Configuration

The configuration for Fabricatio is managed via environment variables or TOML files. The default configuration file (`config.toml`) can be overridden by specifying a custom path.

Example `config.toml`:

```toml
[llm]
api_endpoint = "https://api.openai.com"
api_key = "your_openai_api_key"
timeout = 300
max_retries = 3
model = "gpt-3.5-turbo"
temperature = 1.0
stop_sign = ["\n\n\n", "User:"]
top_p = 0.35
generation_count = 1
stream = false
max_tokens = 8192
```

### Development Setup

To set up a development environment for Fabricatio:

1. **Clone the Repository**:
   ```bash
   git clone https://github.com/Whth/fabricatio.git
   cd fabricatio
   ```

2. **Install Dependencies**:
   ```bash
   uv --with-editable . maturin develop --uv -r
   ```

3. **Run Tests**:
   ```bash
   make test
   ```

4. **Build Documentation**:
   ```bash
   make docs
   ```

### Contributing

Contributions are welcome! Please follow these guidelines when contributing:

1. Fork the repository.
2. Create your feature branch (`git checkout -b feature/new-feature`).
3. Commit your changes (`git commit -am 'Add new feature'`).
4. Push to the branch (`git push origin feature/new-feature`).
5. Create a new Pull Request.

### License

Fabricatio is licensed under the MIT License. See [LICENSE](LICENSE) for more details.

### Acknowledgments

Special thanks to the contributors and maintainers of:
- [PyO3](https://github.com/PyO3/pyo3)
- [Maturin](https://github.com/PyO3/maturin)
- [Handlebars.rs](https://github.com/sunng87/handlebars-rust)



            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "fabricatio",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.12",
    "maintainer_email": null,
    "keywords": "ai, agents, multi-agent, llm, pyo3",
    "author": null,
    "author_email": "Whth <zettainspector@foxmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/ed/52/b24f0ca42cfe89eb839c975b9daad347bc3dcdc1a724d802db0e85643317/fabricatio-0.2.1.tar.gz",
    "platform": null,
    "description": "\n# Fabricatio\n\n![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)\n![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)\n![Build Status](https://img.shields.io/badge/build-passing-brightgreen)\n\nFabricatio is a Python library designed for building LLM (Large Language Model) applications using an event-based agent structure. It integrates Rust for performance-critical tasks, utilizes Handlebars for templating, and employs PyO3 for Python bindings.\n\n## Features\n\n- **Event-Based Architecture**: Utilizes an EventEmitter pattern for robust task management.\n- **LLM Integration**: Supports interactions with large language models for intelligent task processing.\n- **Templating Engine**: Uses Handlebars for dynamic content generation.\n- **Toolboxes**: Provides predefined toolboxes for common operations like file manipulation and arithmetic.\n- **Async Support**: Fully asynchronous for efficient execution.\n- **Extensible**: Easy to extend with custom actions, workflows, and tools.\n\n## Installation\n\n### Using UV (Recommended)\n\nTo install Fabricatio using `uv` (a package manager for Python):\n\n```bash\n# Install uv if not already installed\npip install uv\n\n# Clone the repository\ngit clone https://github.com/Whth/fabricatio.git\ncd fabricatio\n\n# Install the package in development mode with uv\nuv --with-editable . maturin develop --uv -r\n```\n\n### Building Distribution\n\nFor production builds:\n\n```bash\n# Build distribution packages\nmake bdist\n```\n\nThis will generate distribution files in the `dist` directory.\n\n## Usage\n\n### Basic Example\n\nBelow are some basic examples demonstrating how to use Fabricatio for different purposes.\n\n#### Simple Hello World Program\n\n```python\nimport asyncio\nfrom fabricatio import Action, Role, Task, logger\n\n\nclass Hello(Action):\n    \"\"\"Action that says hello.\"\"\"\n\n    name: str = \"hello\"\n    output_key: str = \"task_output\"\n\n    async def _execute(self, task_input: Task[str], **_) -> Any:\n        ret = \"Hello fabricatio!\"\n        logger.info(\"executing talk action\")\n        return ret\n\n\nasync def main() -> None:\n    \"\"\"Main function.\"\"\"\n    role = Role(\n        name=\"talker\", \n        description=\"talker role\", \n        registry={Task.pending_label: WorkFlow(name=\"talk\", steps=(Hello,))}\n    )\n\n    task = Task(name=\"say hello\", goal=\"say hello\", description=\"say hello to the world\")\n    result = await task.delegate()\n    logger.success(f\"Result: {result}\")\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n#### Writing and Dumping Code\n\n```python\nimport asyncio\nfrom fabricatio import Action, Event, PythonCapture, Role, Task, ToolBox, WorkFlow, fs_toolbox, logger\n\n\nclass WriteCode(Action):\n    \"\"\"Action that writes code based on a prompt.\"\"\"\n\n    name: str = \"write code\"\n    output_key: str = \"source_code\"\n\n    async def _execute(self, task_input: Task[str], **_) -> str:\n        return await self.aask_validate(\n            task_input.briefing,\n            validator=PythonCapture.capture,\n        )\n\n\nclass DumpCode(Action):\n    \"\"\"Action that dumps code to the file system.\"\"\"\n\n    name: str = \"dump code\"\n    description: str = \"Dump code to file system\"\n    toolboxes: set[ToolBox] = {fs_toolbox}\n    output_key: str = \"task_output\"\n\n    async def _execute(self, task_input: Task, source_code: str, **_) -> Any:\n        path = await self.handle_fin_grind(task_input, {\"source_code\": source_code})\n        return path[0] if path else None\n\n\nasync def main() -> None:\n    \"\"\"Main function.\"\"\"\n    role = Role(\n        name=\"Coder\",\n        description=\"A python coder who can write and document code\",\n        registry={\n            Event.instantiate_from(\"coding.*\").push(\"pending\"): WorkFlow(\n                name=\"write code\", steps=(WriteCode, DumpCode)\n            ),\n        },\n    )\n\n    prompt = \"write a Python CLI app which prints 'hello world' n times with detailed Google-style docstring. Write the source code to `cli.py`.\"\n\n    proposed_task = await role.propose(prompt)\n    path = await proposed_task.move_to(\"coding\").delegate()\n    logger.success(f\"Code Path: {path}\")\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n#### Proposing Tasks\n\n```python\nimport asyncio\nfrom typing import Any\n\nfrom fabricatio import Action, Role, Task, WorkFlow, logger\n\n\nclass WriteDocumentation(Action):\n    \"\"\"Action that generates documentation for the code in markdown format.\"\"\"\n\n    name: str = \"write documentation\"\n    description: str = \"Write detailed documentation for the provided code.\"\n    output_key: str = \"task_output\"\n\n    async def _execute(self, task_input: Task[str], **_) -> str:\n        return await self.aask(task_input.briefing)\n\n\nasync def main() -> None:\n    \"\"\"Main function.\"\"\"\n    role = Role(\n        name=\"Documenter\",\n        description=\"Role responsible for writing documentation.\",\n        registry={\n            \"doc.*\": WorkFlow(name=\"write documentation\", steps=(WriteDocumentation,))\n        }\n    )\n\n    prompt = \"write a Rust clap CLI that downloads an HTML page\"\n    proposed_task = await role.propose(prompt)\n    documentation = await proposed_task.move_to(\"doc\").delegate()\n    logger.success(f\"Documentation:\\n{documentation}\")\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n#### Complex Workflow Handling\n\n```python\nimport asyncio\nfrom fabricatio import Action, Event, Role, Task, WorkFlow, logger\n\n\nclass WriteCode(Action):\n    \"\"\"Action that writes code based on a prompt.\"\"\"\n\n    name: str = \"write code\"\n    output_key: str = \"source_code\"\n\n    async def _execute(self, task_input: Task[str], **_) -> str:\n        return await self.aask_validate(\n            task_input.briefing,\n            validator=PythonCapture.capture,\n        )\n\n\nclass WriteDocumentation(Action):\n    \"\"\"Action that generates documentation for the code in markdown format.\"\"\"\n\n    name: str = \"write documentation\"\n    description: str = \"Write detailed documentation for the provided code.\"\n    output_key: str = \"task_output\"\n\n    async def _execute(self, task_input: Task[str], **_) -> str:\n        return await self.aask(task_input.briefing)\n\n\nasync def main() -> None:\n    \"\"\"Main function.\"\"\"\n    role = Role(\n        name=\"Developer\",\n        description=\"A developer who can write code and documentation.\",\n        registry={\n            Event.instantiate_from(\"coding.*\").push(\"pending\"): WorkFlow(\n                name=\"write code\", steps=(WriteCode,)\n            ),\n            Event.instantiate_from(\"doc.*\").push(\"pending\"): WorkFlow(\n                name=\"write documentation\", steps=(WriteDocumentation,)\n            ),\n        }\n    )\n\n    # Propose a coding task\n    code_task_prompt = \"write a Python CLI app which adds numbers from a file.\"\n    proposed_task = await role.propose(code_task_prompt)\n    code = await proposed_task.move_to(\"coding\").delegate()\n    logger.success(f\"Code:\\n{code}\")\n\n    # Propose a documentation task\n    doc_task_prompt = f\"{code}\\n\\nwrite Readme.md file for the above code.\"\n    proposed_doc_task = await role.propose(doc_task_prompt)\n    documentation = await proposed_doc_task.move_to(\"doc\").delegate()\n    logger.success(f\"Documentation:\\n{documentation}\")\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n### Advanced Examples\n\n#### Template Management and Rendering\n\n```python\nfrom fabricatio._rust_instances import template_manager\n\ntemplate_name = \"claude-xml.hbs\"\ndata = {\n    \"absolute_code_path\": \"/path/to/project\",\n    \"source_tree\": \"source tree content\",\n    \"files\": [{\"path\": \"file1.py\", \"code\": \"print('Hello')\"}],\n}\n\nrendered_template = template_manager.render_template(template_name, data)\nprint(rendered_template)\n```\n\n#### Handling Security Vulnerabilities\n\n```python\nfrom fabricatio.models.usages import ToolBoxUsage\nfrom fabricatio.models.task import Task\n\ntoolbox_usage = ToolBoxUsage()\n\nasync def handle_security_vulnerabilities():\n    task = Task(\n        name=\"Security Check\",\n        goal=[\"Identify security vulnerabilities\"],\n        description=\"Perform a thorough security review on the project.\",\n        dependencies=[\"./src/main.py\"]\n    )\n    \n    vulnerabilities = await toolbox_usage.gather_tools_fine_grind(task)\n    for vulnerability in vulnerabilities:\n        print(f\"Found vulnerability: {vulnerability.name}\")\n```\n\n#### Managing CTF Challenges\n\n```python\nimport asyncio\n\nfrom fabricatio.models.usages import ToolBoxUsage\nfrom fabricatio.models.task import Task\n\ntoolbox_usage = ToolBoxUsage()\n\nasync def solve_ctf_challenge(challenge_name: str, challenge_description: str, files: list[str]):\n    task = Task(\n        name=challenge_name,\n        goal=[f\"Solve {challenge_name} challenge\"],\n        description=challenge_description,\n        dependencies=files\n    )\n    \n    solution = await toolbox_usage.gather_tools_fine_grind(task)\n    print(f\"Challenge Solved: {solution}\")\n\nif __name__ == \"__main__\":\n    asyncio.run(solve_ctf_challenge(\"Binary Exploitation\", \"CTF Binary Exploitation Challenge\", [\"./challenges/binary_exploit\"]))\n```\n\n### Configuration\n\nThe configuration for Fabricatio is managed via environment variables or TOML files. The default configuration file (`config.toml`) can be overridden by specifying a custom path.\n\nExample `config.toml`:\n\n```toml\n[llm]\napi_endpoint = \"https://api.openai.com\"\napi_key = \"your_openai_api_key\"\ntimeout = 300\nmax_retries = 3\nmodel = \"gpt-3.5-turbo\"\ntemperature = 1.0\nstop_sign = [\"\\n\\n\\n\", \"User:\"]\ntop_p = 0.35\ngeneration_count = 1\nstream = false\nmax_tokens = 8192\n```\n\n### Development Setup\n\nTo set up a development environment for Fabricatio:\n\n1. **Clone the Repository**:\n   ```bash\n   git clone https://github.com/Whth/fabricatio.git\n   cd fabricatio\n   ```\n\n2. **Install Dependencies**:\n   ```bash\n   uv --with-editable . maturin develop --uv -r\n   ```\n\n3. **Run Tests**:\n   ```bash\n   make test\n   ```\n\n4. **Build Documentation**:\n   ```bash\n   make docs\n   ```\n\n### Contributing\n\nContributions are welcome! Please follow these guidelines when contributing:\n\n1. Fork the repository.\n2. Create your feature branch (`git checkout -b feature/new-feature`).\n3. Commit your changes (`git commit -am 'Add new feature'`).\n4. Push to the branch (`git push origin feature/new-feature`).\n5. Create a new Pull Request.\n\n### License\n\nFabricatio is licensed under the MIT License. See [LICENSE](LICENSE) for more details.\n\n### Acknowledgments\n\nSpecial thanks to the contributors and maintainers of:\n- [PyO3](https://github.com/PyO3/pyo3)\n- [Maturin](https://github.com/PyO3/maturin)\n- [Handlebars.rs](https://github.com/sunng87/handlebars-rust)\n\n\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A LLM multi-agent framework.",
    "version": "0.2.1",
    "project_urls": {
        "Homepage": "https://github.com/Whth/fabricatio",
        "Issues": "https://github.com/Whth/fabricatio/issues",
        "Repository": "https://github.com/Whth/fabricatio"
    },
    "split_keywords": [
        "ai",
        " agents",
        " multi-agent",
        " llm",
        " pyo3"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "8531cb064271a04345e72e01a925d077563838b4723f23676f3098854edc8577",
                "md5": "2339d156f4452049e0ce2cbb58c41acf",
                "sha256": "a52af33a5f94599d33a38faf4bf90c1d1c8cae5949cfead305d31ecde96b8ecb"
            },
            "downloads": -1,
            "filename": "fabricatio-0.2.1-cp312-cp312-manylinux_2_34_x86_64.whl",
            "has_sig": false,
            "md5_digest": "2339d156f4452049e0ce2cbb58c41acf",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.12",
            "size": 2209782,
            "upload_time": "2025-02-21T11:56:22",
            "upload_time_iso_8601": "2025-02-21T11:56:22.106855Z",
            "url": "https://files.pythonhosted.org/packages/85/31/cb064271a04345e72e01a925d077563838b4723f23676f3098854edc8577/fabricatio-0.2.1-cp312-cp312-manylinux_2_34_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "7833dd1a2e7c1bb82b7c3efb62bbc9f7d9e65014487ac6d22ad1468865cd3f75",
                "md5": "dc7f364e08a169d3b2c8071751c56091",
                "sha256": "037e015cc72bd422372be9b52a86e8e2a3609c8f13599c58228a28998f7a0213"
            },
            "downloads": -1,
            "filename": "fabricatio-0.2.1-cp312-cp312-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "dc7f364e08a169d3b2c8071751c56091",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.12",
            "size": 1813352,
            "upload_time": "2025-02-21T11:58:47",
            "upload_time_iso_8601": "2025-02-21T11:58:47.840039Z",
            "url": "https://files.pythonhosted.org/packages/78/33/dd1a2e7c1bb82b7c3efb62bbc9f7d9e65014487ac6d22ad1468865cd3f75/fabricatio-0.2.1-cp312-cp312-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "ed52b24f0ca42cfe89eb839c975b9daad347bc3dcdc1a724d802db0e85643317",
                "md5": "fb15dd943cdb1bb23236c8a0c9620b43",
                "sha256": "9522c9e275ff4106ebfbe802ca74750355416b0dd20ccc9add2476f851c156d2"
            },
            "downloads": -1,
            "filename": "fabricatio-0.2.1.tar.gz",
            "has_sig": false,
            "md5_digest": "fb15dd943cdb1bb23236c8a0c9620b43",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.12",
            "size": 157499,
            "upload_time": "2025-02-21T11:56:24",
            "upload_time_iso_8601": "2025-02-21T11:56:24.848689Z",
            "url": "https://files.pythonhosted.org/packages/ed/52/b24f0ca42cfe89eb839c975b9daad347bc3dcdc1a724d802db0e85643317/fabricatio-0.2.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-02-21 11:56:24",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Whth",
    "github_project": "fabricatio",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "fabricatio"
}
        
Elapsed time: 0.42908s