Multiple refs in YAML duplicated mapping key at line 43 error - yaml

I am trying to get multiple refs into a YAML document to break down the size but get duplicated mapping key at line 43 error, is there a way to do this ? or am I just trying to break it down to much, the initial entry file goes to paths
'''
paths:
$ref: "./paths/_index.yaml"
then from there seperates to :
/Users:
get:
$ref: "./user/listUsers.yaml"
post:
$ref: "./user/createUsers.yaml"
/Users/{UserId}:
get:
$ref: "./user/showUserById.yaml"
list users then goes onto users schema as so :
content:
application/json:
schema:
ArrayOfUsers:
type: array
items:
$ref: '../../schemas/User.yaml'
'404':
description: no users were found
default:
$ref: "../../responses/UnexpectedError.yaml"
I then wanted to break up the parts in the users model so I could use them again instead of having a giant block
type: object
description: random corp
properties:
# contact_info:
# description: contact information
# type: object
# properties:
# firstName:
# type: string
# lastName:
# type: string
# companyName:
# type: string
# email:
# type: string
# phone:
# type: string
# address_info:
# description: address information of the alitus customer
# type: object
# properties:
# firstName:
# type: string
# lastName:
# type: string
# companyName:
# type: string
# email:
# type: string
# phone:
# type: string
# account_reference:
# description: Alitus customers number and id for referencing
# type: object
# properties:
# id:
# type: integer
# format: int64
# accountNumber:
# type: integer
# format: int64
$ref: "/Login/LoginDetails.yaml"
$ref: "/packageDetails/PackageDetails.yaml"
example:
type: array
items:
anyOf:
$ref: "../examples/UserExample.yaml"
xml:
name: User
Am I trying to separate it to much or can this be done in 3.0
here is the error
There was an error while processing your files. Please fix the error and save the file.
#/paths/~1Users/get/responses/200/content/application~1json/schema: duplicated mapping key at line 43, column 3:
$ref: ../../schemas/User.yaml
#/paths/~1Users~1{UserId}/get/responses/200/content/application~1json/schema: duplicated mapping key at line 43, column 3:
$ref: ../../schemas/User.yaml
#/components/schemas/User: duplicated mapping key at line 43, column 3:
$ref: ./User.yaml

I figured it out, I just had to have one reference to an object that contained the multiple elements
so now I just call one
$ref: "/test.yaml"
and in the test file we just reference all the objects like so
Login:
$ref: "/Login/LoginDetails.yaml"
Package:
$ref: "/packageDetails/PackageDetails.yaml"

Related

Is it possible to nest YAML anchors hierarchically?

I'm new to working with YAML. I'd like to know if it is possible to 'nest' YAML anchors as I have attempted in the example below. Unfortunately, I get an error YAMLException: unidentified alias "foo" at line 13, column 19: category: *foo ^
namespace: &namespace-definition
name: "Hellow world"
value: "hw"
categories: &categories
- &foo:
name: "foo"
namespace: *namespace-definition
- &bar:
name: "bar"
namespace: *namespace-definition
keys:
- name: "element1"
category: *foo
- name: "element2"
category: *bar
Is there another way to achieve what I am trying to do, or is it impossible?
The anchors in your example are named foo: and bar:, not foo and bar.
Remove the colon after them and it will work:
namespace: &namespace-definition
name: "Hellow world"
value: "hw"
categories: &categories
- &foo
name: "foo"
namespace: *namespace-definition
- &bar
name: "bar"
namespace: *namespace-definition
keys:
- name: "element1"
category: *foo
- name: "element2"
category: *bar

Update hash values with hash key

I'm facing a problem that I couldn't find a working solution yet.
I have my YAML config file for the environment, let's call it development.yml.
This file is used to create the hash that should be updated:
data = YAML.load_file(File.join(Rails.root, 'config', 'environments', 'development.yml'))
What I'm trying to accomplish is something along these lines. Let's suppose we have an element of the sort
data['server']['test']['user']
data['server']['test']['password']
What I want to have is:
data['server']['test']['user'] = #{Server.Test.User}
data['server']['test']['password'] = #{Server.Test.Password}
The idea is to create a placeholder for each value that is the key mapping for that value dynamically, going until the last level of the hash and replacing the value with the mapping to this value, concatenating the keys.
Sorry, it doesn't solve my problem. The location data['server']['test']['user'] will be built dynamically, via a loop that will go through a nested Hash. The only way I found to do it was to append to the string the key for the current iteration of the Hash. At the end, I have a string like "data['server']['test']['name']", which I was thinking on converting to a variable data['server']['test']['name'] and then assigning to this variable the value #{Server.Test.Name}. Reading my question I'm not sure if this is clear, I hope this helps to clarify it.
Input sample:
api: 'active'
server:
test:
user: 'test'
password: 'passwordfortest'
prod:
user: 'nottest'
password: 'morecomplicatedthantest'
In this case, the final result should be to update this yml file in this way:
api: #{Api}
server:
test:
user: #{Server.Test.User}
password: #{Server.Test.Password}
prod:
user: #{Server.Prod.User}
password: #{Server.Prod.Password}
It sounds silly, but I couldn't figure out a way to do it.
I am posting another answer now since I realize what the question is all about.
Use Iteraptor gem:
require 'iteraptor'
require 'yaml'
# or load from file
yaml = <<-YAML.squish
api: 'active'
server:
test:
user: 'test'
password: 'passwordfortest'
prod:
user: 'nottest'
password: 'morecomplicatedthantest'
YAML
mapped =
yaml.iteraptor.map(full_parent: true) do |parent, (k, _)|
v = parent.map(&:capitalize).join('.')
[k, "\#{#{v}}"]
end
puts YAML.dump(mapped)
#⇒ ---
# api: "#{Api}"
# server:
# test:
# user: "#{Server.Test.User}"
# password: "#{Server.Test.Password}"
# prod:
# user: "#{Server.Prod.User}"
# password: "#{Server.Prod.Password}"
puts YAML.dump(mapped).delete('"')
#⇒ ---
# api: #{Api}
# server:
# test:
# user: #{Server.Test.User}
# password: #{Server.Test.Password}
# prod:
# user: #{Server.Prod.User}
# password: #{Server.Prod.Password}
Use String#%:
input = %|
data['server']['host']['name'] = %{server_host}
data['server']['host']['user'] = %{server_host_user}
data['server']['host']['password'] = %{server_host_password}
|
puts (
input % {server_host: "Foo",
server_host_user: "Bar",
server_host_password: "Baz"})
#⇒ data['server']['host']['name'] = Foo
# data['server']['host']['user'] = Bar
# data['server']['host']['password'] = Baz
You can not add key-value pair to a string.
data['server']['host'] # => which results in a string
Option 1:
You can either save Server.Host as host name in the hash
data['server']['host']['name'] = "#{Server.Host}"
data['server']['host']['user'] = "#{Server.Host.User}"
data['server']['host']['password'] = "#{Server.Host.Password}"
Option 2:
You can construct the hash in a single step with Host as key.
data['server']['host'] = { "#{Server.Host}" => {
'user' => "#{Server.Host.User}",
'password' => "#{Server.Host.Password}"
}
}

How to show parameters of Grape API when it is hash or array and the inside value isn't defined with swagger doc

I am using swagger doc to generate API document in grape api. API parameters are defined like:
desc "Get results by query"
params do
requires :type, type: String, desc: "search type"
requires :body, type: Hash, desc: "query body"
optional :user, type: Hash, desc: "support search as other user, otherwise search as current user" do
requires :id, type: String, desc: "user id"
requires :name, type: String, desc: "user name (dn)"
requires :directory, type: String, desc: "directory user belongs to"
end
end
post :query do
The generated JSON only shows the user related parameters. How can I define the hash parameters whose key is not restricted and could be generated in API document?

Update value in key value pair in yml file using ruby [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have a YAML file:
DATA_SVC_GEN_CONF_ATTR:
-
-
-
name: validationCodeNum
value: 1
-
name: validationCodeSymbol
value: "val1"
-
name: sql
value: Test
-
name: sqlByGridArea
value: Test1
I want to replace the value of the key sql from "Test" to "Select * from table".
What I am trying is:
asset.getAttributes.getList.each{|a|
if a.getName == "sqlByGridArea"
a.setValue "Select * from table"
(attrib_defs).map!{|a| a.map{|k,v| "#{k}=#{v}"}.join(',')}
end
asset.with_attributes attrib_defs
Here's how to test whether your YAML is valid, and how I generate YAML for use in files or elsewhere:
require 'yaml'
str = <<EOT
DATA_SVC_GEN_CONF_ATTR:
-
-
-
name: validationCodeNum
value: 1
-
name: validationCodeSymbol
value: "val1"
-
name: sql
value: Test
-
name: sqlByGridArea
value: Test1
EOT
data = YAML.load(str)
# => {"DATA_SVC_GEN_CONF_ATTR"=>
# [[[{"name"=>"validationCodeNum", "value"=>1},
# {"name"=>"validationCodeSymbol", "value"=>"val1"},
# {"name"=>"sql", "value"=>"Test"},
# {"name"=>"sqlByGridArea", "value"=>"Test1"}]]]}
YAML would complain if it couldn't parse the data. If it could and the data wasn't what you expect the output help you diagnose the problem.
When I want to create a YAML file, especially one that's complex, I start with the actual data structure and let YAML generate the serialized version of it:
data = {
'DATA_SVC_GEN_CONF_ATTR' =>
[
[
[
{
'name' => 'validationCodeNum',
'value' => 1
},
{
'name' => 'validationCodeSymbol',
'value' => 'val1'
},
{
'name' => 'sql',
'value' => 'Test'
},
{
'name' => 'sqlByGridArea',
'value' => 'Test1'
}
]
]
]
}
puts data.to_yaml
# >> ---
# >> DATA_SVC_GEN_CONF_ATTR:
# >> - - - name: validationCodeNum
# >> value: 1
# >> - name: validationCodeSymbol
# >> value: val1
# >> - name: sql
# >> value: Test
# >> - name: sqlByGridArea
# >> value: Test1
Moving on... To change elements in a YAML file you can treat the file as text, read it line-by-line, read it by slurping it, or have YAML open it and change the resulting object then have YAML rewrite it.
Slurping files is OK if you're sure the data will fit in memory and you can easily find the section you want to change. Reading it line-by-line often makes it easier to find specific text because you're dealing with individual lines, not the whole file.
Using YAML is the easiest I think as it reduces the change of a badly written regex doing the wrong thing.
data = <<EOT
---
DATA_SVC_GEN_CONF_ATTR:
- - - name: validationCodeNum
value: 1
- name: validationCodeSymbol
value: val1
- name: sql
value: Test
- name: sqlByGridArea
value: Test1
EOT
Pretending that data was the content of a YAML file on disk, it'd be loaded and parsed using YAML.load_file. In this example I'm loading as a string so I have to use load:
object = YAML.load(data)
The data is now parsed so it can be manipulated easily:
object['DATA_SVC_GEN_CONF_ATTR'].first.first[2]['name'] = "Select * from table"
Then it can be written back out:
puts object.to_yaml # => nil
# >> ---
# >> DATA_SVC_GEN_CONF_ATTR:
# >> - - - name: validationCodeNum
# >> value: 1
# >> - name: validationCodeSymbol
# >> value: val1
# >> - name: Select * from table
# >> value: Test
# >> - name: sqlByGridArea
# >> value: Test1
If this is a mission-critical (production) file, you'd want to do the appropriate rename, write, delete steps to protect the data in-case of errors, but that's the gist of it.
Your data structure is very questionable though. You're using a nested array-of-array-of-array just to hold your hashes, which is not very common or easily understood. Instead it should be reduced to a single array:
data = <<EOT
---
DATA_SVC_GEN_CONF_ATTR:
- name: validationCodeNum
value: 1
- name: validationCodeSymbol
value: val1
- name: sql
value: Test
- name: sqlByGridArea
value: Test1
EOT
object = YAML.load(data)
# => {"DATA_SVC_GEN_CONF_ATTR"=>
# [{"name"=>"validationCodeNum", "value"=>1},
# {"name"=>"validationCodeSymbol", "value"=>"val1"},
# {"name"=>"sql", "value"=>"Test"},
# {"name"=>"sqlByGridArea", "value"=>"Test1"}]}
object['DATA_SVC_GEN_CONF_ATTR'][2]['name'] = "Select * from table"

sending a form with mechanzie(Ruby) returns and empty page?

I want to scrape the list of offers of a given product from amazon.com with the quantity in stoke for each offer.
To find this last information (quantity) I need to add that offer to cart, than edit the cart with the quantity 999. and than get the quantity from the next page.
take for example this product (http://www.amazon.com/gp/offer-listing/B00DW58ENU/ref=olp_tab_all&startIndex=1) the button Add to Cart is a form with a single submit. I can find the form with the code
offer_form = agent.page.forms_with(action: /item-dispatch/)[0]
##<Mechanize::Form
# {name nil}
# {method "POST"}
#{action "/gp/item-dispatch/ref=olp_atc_new_1/181-7026511-7466349"}
# {fields
# [hidden:0x1717018 type: hidden name: session-id value: 181-7026511-7466349]
# [hidden:0x1716a8c type: hidden name: qid value: ]
# [hidden:0x1716514 type: hidden name: sr value: ]
# [hidden:0x1715eac type: hidden name: signInToHUC value: 0]
# [hidden:0x17155d8 type: hidden name: metric-asin.B00NHQFA1I value: 1]
# [hidden:0x1714e80 type: hidden name: registryItemID.1 value: ]
# [hidden:0x1714a0c type: hidden name: registryID.1 value: ]
# [hidden:0x1714598 type: hidden name: quantity.1 value: 1]
# [hidden:0x1714138 type: hidden name: offeringID.1 value: RVm%2FgzxznRorTyxf%2F8fiGjVFjfScvgO1JJBElusLb7hLttElaCwmvhKe7NSGkE1LBMGmkM3oodMhTTBnKT%2FCP%2FnFeT7SBoLZdnRfmVwRFa0N7AHRTVnphw%3D%3D]
# [hidden:0x1707938 type: hidden name: isAddon value: 0]}
# {radiobuttons}
# {checkboxes}
# {file_uploads}
# {buttons
# [submit:0x17072e4 type: submit name: submit.addToCart value: Add to #cart]}>
page = offer_form.submit
##<Mechanize::Page
# {url #<URI::HTTP http://www.amazon.com/gp/item-dispatch/ref=olp_atc_new_1>}
# {meta_refresh}
# {title nil}
# {iframes}
# {frames}
# {links}
# {forms}>
I am wondering why I got this empty page as a result.
I though that maybe this is because the action is different than the real one found when I open the page using the browser (Chrome of Firefox).
but even if I change the offer_form.action to be like that found on the browser. It does not change the result, and I still get an empty page.

Resources