# PythonPoet

API for generating Python source code from runtime. It can be useful for generating types' files, interacting with
metadata and creating auto-generated code.

### Getting Started

PythonPoet allows you to very quickly start working on your first autogenerated code. In order to simplify generation
process, we've created a lot of simply-to-use builders.

#### Installation

PythonPoet requires **Python 3.10 or newer**. You can install this module using Pip and PyPI: `pip install PythonPoet`.

#### Creating class

So, after you've installed PythonPoet, you'll want to generate your first class. It's very, very simple. First of all,
you'll need to create a new instance of the `PythonPoet` class. You need to know that `PythonPoet` class is a class that
manages everything during the generation process. Let's see an example:

```python
import pythonpoet

poet = pythonpoet.PythonPoet()
```

Moving on. Now, after you've created a `PythonPoet` class, you can start generating methods and classes. In order to
create your first class, you'll need to call `.add_class` method on the `PythonPoet` instance. This method takes only
one argument - class' builder. This is an example:

```python
poet.add_class(
    pythonpoet.ClassBuilder()
    .set_name('YourClassName')
)
```

That's it. You've created your first class using `PythonPoet`. Let's move on creating methods, fields and decorating the
class. By the way, you can combine class with methods, fields and decorators.

#### Creating method

Creating your first method is simple as creating your first class. The principle are more or less the same. You'll need
to use `MethodBuilder` class, set method's name, arguments, source code and a return type[^type_note]. The only required
field in method
is its name, everything else is optional. Here's an example:

```python
pythonpoet.types.method.MethodBuilder()
.set_name('your_method_name')
.set_source_code('print("Hello, World!")')
```

#### Creating field

Yet again, this technique is similar to what you've done for creating methods and classes itself. You'll need to use
`ClassFieldBuilder` and set its name and type[^type_note] (it's required). Here's an example:

```python
pythonpoet.ClassFieldBuilder()
.set_name('your_field_name')
.set_type(str)
```

### Need help?

Join our [Discussions](https://github.com/Pelfox/PythonPoet/discussions) in order to get any help with this library.
Feel free to ask any library-related questions.

### License

Everything licensed with MIT license, unless otherwise specified.

### Contributing

First of all, thank you for your interest in help with maintaining this library. Your support is greatly appreciated.
So, in order to contribute, you firstly need to read our [Contribution Guidelines](.github/CODE_OF_CONDUCT.md). After
that, you can read [Contribution guide](.github/CONTRIBUTION.md) and pick
any [issue](https://github.com/Pelfox/PythonPoet/issues) that you think you can help with.

[^type_note]:
    If you want to use non-primitive type, you'll need to create an import for it. Here's an
    example: `ImportBuilder().set_class_name("dataclass").set_module_name("dataclasses")`, which will convert
    into `from dataclasses import dataclass`. After you've created an import, you can pass it along with your
    type: `.set_type(dataclass, ImportBuilder().set_class_name("dataclass").set_module_name("dataclasses"))`.