easy_talk 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8455d741b05a1a65ca7ea3f7e2d529271414fb04881066cc81bbb444399e200c
4
- data.tar.gz: 9814e429530dbb42da5a3cca3310175ebe98038d91d5b7deeddcd68aa90b3199
3
+ metadata.gz: d3b84eeed5e8d6430c3bbaf97936ec90a29554dcbd71905553ecaf2f66b82877
4
+ data.tar.gz: 74fa329ca8574c8d8d8ec2b3daf6dee3a8d46a3550c53fb30ceb1709487243d9
5
5
  SHA512:
6
- metadata.gz: 5a85e59b3eaa7e0e9c2d57eb0283f2b4a45e6dfeb88778682738969617f751149aaf99cd93b4760c323eb84da476ac0ee8aba59eef003156d8d82aae60a940fd
7
- data.tar.gz: 0c382d7989016e5a1c376439c96cd8b1d4acb7a6758a8fb2b406239551445ede641fb3a3ed64f833ce591409a75eefb0f3023a4a60cfffc92ca49ee5827bc24d
6
+ metadata.gz: 59be99a0311ec3c5d941e63cc2299e26d2a84c1a53ff88f6bd561dbd1b046dc3f4e5d68c8037724cd295df8d542a7a24621374cc535422920200a11ae66507e5
7
+ data.tar.gz: 2eabc32e703f00a68d47d1152fc1a42cc963e0f5ba05aea76b57b7ccccde670dcb4361811b8af812b85d2c78880f7b375e536d7ce7f0f12a7177dd8b80046775
data/.rubocop.yml CHANGED
@@ -27,4 +27,7 @@ Layout/LineLength:
27
27
 
28
28
  RSpec/DescribeClass:
29
29
  Exclude:
30
- - 'spec/easy_talk/examples/**/*'
30
+ - 'spec/easy_talk/examples/**/*'
31
+
32
+ RSpec/MultipleExpectations:
33
+ Max: 4
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## [0.2.1] - 2024-05-06
2
+ - Run JSON Schema validations using ActiveModel's validations.
3
+
1
4
  ## [0.2.0] - 2024-05-01
2
5
  - Added ActiveModel::API functionality to EasyTalk::Model module. That means you get all the benefits of ActiveModel::API including attribute assignment, introspections, validations, translation (i18n) and more. See https://api.rubyonrails.org/classes/ActiveModel/API.html for more information.
3
6
 
data/README.md CHANGED
@@ -1,6 +1,16 @@
1
1
  # EasyTalk
2
2
 
3
- EasyTalk is a Ruby library for defining and generating JSON Schema.
3
+ EasyTalk is a Ruby library that simplifies defining and generating JSON Schema documents, and validates that JSON data conforms to these schemas.
4
+
5
+ Key Features
6
+ * Intuitive Schema Definition: Use Ruby classes and methods to define JSON Schema documents easily.
7
+ * JSON Schema Compliance: Implements the JSON Schema specification to ensure compatibility and standards adherence.
8
+ * LLM Function Support: Ideal for integrating with Large Language Models (LLMs) such as OpenAI's GPT-3.5-turbo and GPT-4. EasyTalk enables you to effortlessly create JSON Schema documents needed to describe the inputs and outputs of LLM function calls.
9
+ * Validation: Validates JSON inputs and outputs against defined schemas to ensure they meet expected formats and types. Write custom validations using ActiveModel's validations.
10
+ * Integration with ActiveModel: EasyTalk integrates with ActiveModel to provide additional functionality such as attribute assignment, introspections, validations, translation (i18n), and more.
11
+
12
+ Inspiration
13
+ Inspired by Python's Pydantic library, EasyTalk brings similar functionality to the Ruby ecosystem, providing a Ruby-friendly approach to JSON Schema operations.
4
14
 
5
15
  Example Use:
6
16
 
@@ -7,48 +7,55 @@ require 'active_support/time'
7
7
  require 'active_support/concern'
8
8
  require 'active_support/json'
9
9
  require 'active_model'
10
- require 'json-schema'
10
+ require 'json_schemer'
11
+ require_relative 'schema_errors_mapper'
11
12
  require_relative 'builders/object_builder'
12
13
  require_relative 'schema_definition'
13
14
 
14
15
  module EasyTalk
15
- # The Model module can be included in a class to add JSON schema definition and generation support.
16
+ # The `Model` module is a mixin that provides functionality for defining and accessing the schema of a model.
17
+ #
18
+ # It includes methods for defining the schema, retrieving the schema definition,
19
+ # and generating the JSON schema for the model.
20
+ #
21
+ # Example usage:
22
+ #
23
+ # class Person
24
+ # include EasyTalk::Model
25
+ #
26
+ # define_schema do
27
+ # property :name, String, description: 'The person\'s name'
28
+ # property :age, Integer, description: 'The person\'s age'
29
+ # end
30
+ # end
31
+ #
32
+ # Person.json_schema #=> returns the JSON schema for Person
33
+ # jim = Person.new(name: 'Jim', age: 30)
34
+ # jim.valid? #=> returns true
35
+ #
36
+ # @see SchemaDefinition
16
37
  module Model
17
- # The `Model` module is a mixin that provides functionality for defining and accessing the schema of a model.
18
- #
19
- # It includes methods for defining the schema, retrieving the schema definition,
20
- # and generating the JSON schema for the model.
21
- #
22
- # Example usage:
23
- #
24
- # class Person
25
- # include EasyTalk::Model
26
- #
27
- # define_schema do
28
- # property :name, String, description: 'The person\'s name'
29
- # property :age, Integer, description: 'The person\'s age'
30
- # end
31
- # end
32
- #
33
- # Person.json_schema #=> returns the JSON schema for Person
34
- # jim = Person.new(name: 'Jim', age: 30)
35
- # jim.valid? #=> returns true
36
- #
37
- # @see SchemaDefinition
38
- #
39
38
  def self.included(base)
40
39
  base.include ActiveModel::API # Include ActiveModel::API in the class including EasyTalk::Model
40
+ base.include ActiveModel::Validations
41
+ base.extend ActiveModel::Callbacks
42
+ base.validates_with SchemaValidator
41
43
  base.extend(ClassMethods)
42
44
  end
43
45
 
44
- # Checks if the model is valid.
45
- #
46
- # This method calls the `validate_json` class method on the current class,
47
- # passing the `properties` as the argument.
48
- #
49
- # @return [Boolean] true if the model is valid, false otherwise.
50
- def valid?
51
- self.class.validate_json(properties)
46
+ class SchemaValidator < ActiveModel::Validator
47
+ def validate(record)
48
+ result = schema_validation(record)
49
+ result.errors.each do |key, error_msg|
50
+ record.errors.add key.to_sym, error_msg
51
+ end
52
+ end
53
+
54
+ def schema_validation(record)
55
+ schema = JSONSchemer.schema(record.class.json_schema)
56
+ errors = schema.validate(record.properties)
57
+ SchemaErrorsMapper.new(errors)
58
+ end
52
59
  end
53
60
 
54
61
  # Returns the properties of the model as a hash with symbolized keys.
@@ -94,14 +101,6 @@ module EasyTalk
94
101
  end
95
102
  end
96
103
 
97
- # Validates the given JSON against the model's JSON schema.
98
- #
99
- # @param json [Hash] The JSON to validate.
100
- # @return [Boolean] `true` if the JSON is valid, `false` otherwise.
101
- def validate_json(json)
102
- JSON::Validator.validate(json_schema, json)
103
- end
104
-
105
104
  # Returns the JSON schema for the model.
106
105
  #
107
106
  # @return [Hash] The JSON schema for the model.
@@ -0,0 +1,21 @@
1
+ module EasyTalk
2
+ class SchemaErrorsMapper
3
+ def initialize(errors)
4
+ @errors = errors.to_a
5
+ end
6
+
7
+ def errors
8
+ @errors.each_with_object({}) do |error, hash|
9
+ if error['data_pointer'].present?
10
+ key = error['data_pointer'].split('/').compact_blank.join('.')
11
+ hash[key] = error['error']
12
+ else
13
+ error['details']['missing_keys'].each do |missing_key|
14
+ message = "#{error['error'].split(':').first}: #{missing_key}"
15
+ hash[missing_key] = message
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EasyTalk
4
- VERSION = '0.2.0'
4
+ VERSION = '0.2.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easy_talk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergio Bayona
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-01 00:00:00.000000000 Z
11
+ date: 2024-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -39,19 +39,19 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '7.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: json-schema
42
+ name: json_schemer
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '4'
47
+ version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '4'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: sorbet-runtime
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -213,6 +213,7 @@ files:
213
213
  - lib/easy_talk/model.rb
214
214
  - lib/easy_talk/property.rb
215
215
  - lib/easy_talk/schema_definition.rb
216
+ - lib/easy_talk/schema_errors_mapper.rb
216
217
  - lib/easy_talk/sorbet_extension.rb
217
218
  - lib/easy_talk/tools/function_builder.rb
218
219
  - lib/easy_talk/types/all_of.rb