Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/shtse8/sotischema

A powerful tool for generating schemas from Dart data classes, enabling seamless integration with AI models and data validation systems.
https://github.com/shtse8/sotischema

dart json json-schema schema

Last synced: 6 days ago
JSON representation

A powerful tool for generating schemas from Dart data classes, enabling seamless integration with AI models and data validation systems.

Awesome Lists containing this project

README

        

# SotiSchema

Welcome to **SotiSchema** – your ultimate tool for generating schemas directly from your Dart data classes. Whether you're working with `freezed` or `json_serializable`, SotiSchema simplifies the process, enabling seamless integration with AI models, robust data validation, and more.

---

## 🎯 Why SotiSchema?

**SotiSchema** is designed for developers who value efficiency and precision. If you're tired of manually maintaining schemas and ensuring they stay in sync with your code, SotiSchema is the solution you've been waiting for.

### **Key Benefits:**

- **Effortless Schema Generation:** Simply annotate your Dart classes, and SotiSchema does the rest.
- **AI-Powered Applications:** Generate schemas that enforce structured responses from AI models.
- **Future-Proof:** Prepare for upcoming support of various schema formats, including Protocol Buffers, Avro, and Thrift.
- **Seamless Integration:** Perfectly complements your existing tools, whether you're using `freezed`, `json_serializable`, or custom Dart types.

---

## πŸš€ Getting Started

### Installation

Get started with SotiSchema in just one step:

```bash
dart pub add soti_schema
```

This command will add SotiSchema to your project, ready for immediate use.

### Configuration

To make SotiSchema work harmoniously with `freezed` and `json_serializable`, configure your `build.yaml` file like this:

```yaml
targets:
$default:
builders:
json_serializable:
options:
explicit_to_json: true

global_options:
freezed|freezed:
runs_before:
- soti_schema|openApiBuilder
```

### Why This Configuration?

- **`explicit_to_json: true`** ensures that nested objects are correctly serialized by generating explicit `toJson` methods.
- **`runs_before`** guarantees that `freezed` runs before SotiSchema, ensuring that everything is in place when SotiSchema processes your classes.

---

## πŸ’‘ How to Use SotiSchema

### Example with `freezed`

Here’s how to generate a JSON schema using SotiSchema with a `freezed` class:

```dart
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:soti_schema/soti_schema.dart';

part 'example_model.freezed.dart';
part 'example_model.g.dart';

@freezed
@SotiSchema()
class ExampleModel with _$ExampleModel {
const factory ExampleModel({
@Default('') String name,
@Default(0) int age,
@Default([]) List hobbies,
}) = _ExampleModel;

factory ExampleModel.fromJson(Map json) =>
_$ExampleModelFromJson(json);

@jsonSchema
static String get schema => _$ExampleModelSchema;
}
```

### Example with `json_serializable`

Prefer `json_serializable`? SotiSchema has you covered:

```dart
import 'package:json_annotation/json_annotation.dart';
import 'package:soti_schema/soti_schema.dart';

part 'example_model.g.dart';

@SotiSchema()
@JsonSerializable()
class ExampleModel {
final String name;
final int age;
final List hobbies;

ExampleModel({
this.name = '',
this.age = 0,
this.hobbies = const [],
});

factory ExampleModel.fromJson(Map json) =>
_$ExampleModelFromJson(json);

Map toJson() => _$ExampleModelToJson(this);

@jsonSchema
static String get schema => _$ExampleModelSchema;

@jsonSchema
static Map get schemaMap => _$ExampleModelSchemaMap;
}
```

### Adding Descriptions to Your Schema

When generating schemas with SotiSchema, you can include descriptions for your fields in two ways:

1. **Doc Comments**: Use regular Dart doc comments (`///`) above your class fields. SotiSchema will automatically extract these comments and include them as descriptions in the generated schema.

2. **`@Description` Annotation**: If you prefer more control or want to add descriptions that differ from your doc comments, you can use the `@Description` annotation. This approach allows you to provide explicit descriptions directly.

#### Example with Doc Comments

```dart
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:soti_schema/soti_schema.dart';

part 'example_model.freezed.dart';
part 'example_model.g.dart';

@freezed
@SotiSchema()
class ExampleModel with _$ExampleModel {
const factory ExampleModel({
/// The name of the person.
@Default('') String name,

/// The age of the person in years.
@Default(0) int age,

/// A list of hobbies the person enjoys.
@Default([]) List hobbies,
}) = _ExampleModel;

factory ExampleModel.fromJson(Map json) =>
_$ExampleModelFromJson(json);

@jsonSchema
static String get schema => _$ExampleModelSchema;
}
```

In this example, the doc comments will be used as descriptions in the generated JSON schema.

#### Example with `@Description` Annotation

```dart
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:soti_schema/soti_schema.dart';
import 'package:meta/meta.dart';

part 'example_model.freezed.dart';
part 'example_model.g.dart';

@freezed
@SotiSchema()
class ExampleModel with _$ExampleModel {
const factory ExampleModel({
@Description('The name of the person.')
@Default('') String name,

@Description('The age of the person in years.')
@Default(0) int age,

@Description('A list of hobbies the person enjoys.')
@Default([]) List hobbies,
}) = _ExampleModel;

factory ExampleModel.fromJson(Map json) =>
_$ExampleModelFromJson(json);

@jsonSchema
static String get schema => _$ExampleModelSchema;
}
```

In this example, the `@Description` annotations will be used as descriptions in the generated JSON schema.

### Flexible Schema Naming

With SotiSchema, you have the freedom to name your schema methods however you like and choose between returning a `String` or `Map`. SotiSchema adapts to your needs:

```dart
@jsonSchema
static String get customSchemaName => _$ExampleModelSchema;

@jsonSchema
static Map get anotherSchema => _$ExampleModelSchemaMap;
```

---

## πŸ“‹ Supported Dart Data Types

SotiSchema currently supports:

- **`freezed`**: βœ”οΈ Supported
- **`json_serializable`**: βœ”οΈ Supported

### Coming Soon:

- **Custom Data Types**: πŸ›  Planned
- **Protocol Buffers**: πŸ›  Planned
- **Avro**: πŸ›  Planned
- **Thrift**: πŸ›  Planned

---

## 🌟 Why Developers Love SotiSchema

**"SotiSchema has completely transformed how we handle data validation and AI integrations. The ease of generating accurate schemas directly from our Dart classes is unmatched."**
– *Satisfied Developer*

---

## πŸ’Ό Real-World Use Case

### AI Integration Example

Imagine you’re building an AI-powered application. SotiSchema helps ensure that AI responses adhere to the strict structure defined by your schemas:

```dart
import 'package:langchain/langchain.dart';
import 'package:your_project/example_model.dart'; // Assuming this is where your ExampleModel class is defined

void main() {
final openaiApiKey = 'your-openai-api-key';

final model = ChatOpenAI(
apiKey: openaiApiKey,
defaultOptions: const ChatOpenAIOptions(
responseFormat: ChatOpenAIResponseFormat(
type: ChatOpenAIResponseFormatType.jsonObject,
),
),
);

final parser = JsonOutputParser();
final mapper = Runnable.mapInputStream(
(Stream> inputStream) => inputStream.map((input) {
return ExampleModel.fromJson(input);
}).distinct(),
);

final chain = model.pipe(parser).pipe(mapper);

final stream = chain.stream(
PromptValue.string('''
Describe a person using the schema provided.
${ExampleModel.schema}
'''),
);

stream.listen((response) {
print(response); // This response will be a JSON object that matches your schema
});
}
```

---

## 🀝 Get Involved

We welcome contributions! If you have ideas for new features, enhancements, or bug fixes, please check out our [contributing guidelines](CONTRIBUTING.md).

---

## πŸ“„ License

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

---

Thank you for choosing SotiSchema! We’re excited to see what you create with it. If you have any questions or suggestions, don’t hesitate to open an issue or contribute to the project. Happy coding!