error trying to fetch from database and return result in http response - ecto

If I run Api.Category |> Api.Repo.all in iex I get this response in the terminal (basically I get two rows from the "categories" database table):
iex(1)> Api.Category |> Api.Repo.all
16:21:55.775 [debug] QUERY OK source="categories" db=5.2ms decode=6.3ms
SELECT c0."id", c0."name" FROM "categories" AS c0 []
[%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 1,
name: "Grocery Products"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 2,
name: "Meals"}]
I am trying to send that response back in an http response but am getting this error (I think it is just not retrieving anything from the database).
Poison.EncodeError at GET /categories unable to encode value: {nil, "categories"} lib/poison/encoder.ex
378 def encode(%{__struct__: _} = struct, options) do
379 Poison.Encoder.Map.encode(Map.from_struct(struct), options)
380 end
381
382 def encode(value, _options) do
383 raise Poison.EncodeError, value: value
384 end
385end
Here is my function that tries to get the entries in "categories" database table and return them in an http response:
def getCategories(conn) do
categories = Api.Category |> Api.Repo.all
conn
|> put_resp_content_type("application/json")
|> send_resp(200, Poison.encode!(%{categories: categories}))
end
What am I doing wrong?
I set up the connections:
application.ex:
defmodule Api.Application do
use Application
def start( _type, _args ) do
import Supervisor.Spec, warn: false
children = [
worker(__MODULE__, [], function: :run),
supervisor(Api.Repo, []),
]
opts = [strategy: :one_for_one, name: Api.Supervisor]
Supervisor.start_link(children, opts)
end
def run do
{ :ok, _ } = Plug.Adapters.Cowboy.http Api.Router, []
end
end
repo.ex has all my database queries (including getCategories which should be in a controller) which I have been told is weird but hey, iteration 1, i just wanna get it working first:
defmodule Api.Repo do
use Ecto.Repo, otp_app: :api
require Ecto.Query
import Plug.Conn
def insertCategories do
categories = [
%Api.Category{name: "Grocery Products"},
%Api.Category{name: "Meals"}
]
Enum.each(categories, fn (category) -> insert(category) end)
end
def insertSubcategories do
subcategories = [
%Api.Subcategory{name: "Meat"},
%Api.Subcategory{name: "Dairy"},
%Api.Subcategory{name: "Confectionary"},
%Api.Subcategory{name: "Dessert"},
%Api.Subcategory{name: "Baking"},
%Api.Subcategory{name: "Condiments"},
%Api.Subcategory{name: "Beverages"},
%Api.Subcategory{name: "African"},
%Api.Subcategory{name: "Argentine"},
%Api.Subcategory{name: "Asian"},
%Api.Subcategory{name: "Asian Fusion"},
%Api.Subcategory{name: "BBQ"},
%Api.Subcategory{name: "Bakery"},
%Api.Subcategory{name: "Beverages"},
%Api.Subcategory{name: "Brazilian"},
%Api.Subcategory{name: "Breakfast"},
%Api.Subcategory{name: "British"},
%Api.Subcategory{name: "Cafe"},
%Api.Subcategory{name: "Cambodian"},
%Api.Subcategory{name: "Chinese"},
%Api.Subcategory{name: "Coffee and Tea"},
%Api.Subcategory{name: "Contemporary"},
%Api.Subcategory{name: "Continental"},
%Api.Subcategory{name: "Deli"},
%Api.Subcategory{name: "Desserts"},
%Api.Subcategory{name: "Drinks Only"},
%Api.Subcategory{name: "European"},
%Api.Subcategory{name: "Fijian"},
%Api.Subcategory{name: "Filipino"},
%Api.Subcategory{name: "Finger Food"},
%Api.Subcategory{name: "Fish and Chips"},
%Api.Subcategory{name: "French Fusion"},
%Api.Subcategory{name: "German"},
%Api.Subcategory{name: "Greek"},
%Api.Subcategory{name: "Grill"},
%Api.Subcategory{name: "Healthy Food"},
%Api.Subcategory{name: "Ice Cream"},
%Api.Subcategory{name: "Indian"},
%Api.Subcategory{name: "Indonesian"},
%Api.Subcategory{name: "International"},
%Api.Subcategory{name: "Irish"},
%Api.Subcategory{name: "Italian"},
%Api.Subcategory{name: "Japanese"},
%Api.Subcategory{name: "Jewish"},
%Api.Subcategory{name: "Juices"},
%Api.Subcategory{name: "Kiwi"},
%Api.Subcategory{name: "Korean"},
%Api.Subcategory{name: "Latin"},
%Api.Subcategory{name: "American"},
%Api.Subcategory{name: "Lebanese"},
%Api.Subcategory{name: "Malaysian"},
%Api.Subcategory{name: "Mediterranean"},
%Api.Subcategory{name: "Mexican"},
%Api.Subcategory{name: "Middle Eastern"},
%Api.Subcategory{name: "Mongolian"},
%Api.Subcategory{name: "Moroccan"},
%Api.Subcategory{name: "Nepalese"},
%Api.Subcategory{name: "North Indian"},
%Api.Subcategory{name: "Pacific"},
%Api.Subcategory{name: "Persian"},
%Api.Subcategory{name: "Pizza"},
%Api.Subcategory{name: "Portuguese"},
%Api.Subcategory{name: "Pub Food"},
%Api.Subcategory{name: "Seafood"},
%Api.Subcategory{name: "Singaporean"},
%Api.Subcategory{name: "South Indian"},
%Api.Subcategory{name: "Spanish"},
%Api.Subcategory{name: "Sri Lankan"},
%Api.Subcategory{name: "Steakhouse"},
%Api.Subcategory{name: "Street Food"},
%Api.Subcategory{name: "Sushi"},
%Api.Subcategory{name: "Taiwanese"},
%Api.Subcategory{name: "Thai"},
%Api.Subcategory{name: "Turkish"},
%Api.Subcategory{name: "Vietnamese"},
]
Enum.each(subcategories, fn (subcategory) -> insert(subcategory) end)
end
def insertCategorySubcategories do
categorySubcategories = [
%Api.CategorySubcategory{c_id: 1, s_id: 1},
%Api.CategorySubcategory{c_id: 1, s_id: 2},
%Api.CategorySubcategory{c_id: 1, s_id: 3},
%Api.CategorySubcategory{c_id: 1, s_id: 4},
%Api.CategorySubcategory{c_id: 1, s_id: 5},
%Api.CategorySubcategory{c_id: 1, s_id: 6},
%Api.CategorySubcategory{c_id: 1, s_id: 7},
%Api.CategorySubcategory{c_id: 2, s_id: 8},
%Api.CategorySubcategory{c_id: 2, s_id: 9},
%Api.CategorySubcategory{c_id: 2, s_id: 10},
%Api.CategorySubcategory{c_id: 2, s_id: 11},
%Api.CategorySubcategory{c_id: 2, s_id: 12},
%Api.CategorySubcategory{c_id: 2, s_id: 13},
%Api.CategorySubcategory{c_id: 2, s_id: 14},
%Api.CategorySubcategory{c_id: 2, s_id: 15},
%Api.CategorySubcategory{c_id: 2, s_id: 16},
%Api.CategorySubcategory{c_id: 2, s_id: 17},
%Api.CategorySubcategory{c_id: 2, s_id: 18},
%Api.CategorySubcategory{c_id: 2, s_id: 19},
%Api.CategorySubcategory{c_id: 2, s_id: 20},
%Api.CategorySubcategory{c_id: 2, s_id: 21},
%Api.CategorySubcategory{c_id: 2, s_id: 23},
%Api.CategorySubcategory{c_id: 2, s_id: 24},
%Api.CategorySubcategory{c_id: 2, s_id: 25},
%Api.CategorySubcategory{c_id: 2, s_id: 26},
%Api.CategorySubcategory{c_id: 2, s_id: 27},
%Api.CategorySubcategory{c_id: 2, s_id: 28},
%Api.CategorySubcategory{c_id: 2, s_id: 29},
%Api.CategorySubcategory{c_id: 2, s_id: 30},
%Api.CategorySubcategory{c_id: 2, s_id: 31},
%Api.CategorySubcategory{c_id: 2, s_id: 32},
%Api.CategorySubcategory{c_id: 2, s_id: 33},
%Api.CategorySubcategory{c_id: 2, s_id: 34},
%Api.CategorySubcategory{c_id: 2, s_id: 35},
%Api.CategorySubcategory{c_id: 2, s_id: 36},
%Api.CategorySubcategory{c_id: 2, s_id: 37},
%Api.CategorySubcategory{c_id: 2, s_id: 38},
%Api.CategorySubcategory{c_id: 2, s_id: 39},
%Api.CategorySubcategory{c_id: 2, s_id: 40},
%Api.CategorySubcategory{c_id: 2, s_id: 41},
%Api.CategorySubcategory{c_id: 2, s_id: 42},
%Api.CategorySubcategory{c_id: 2, s_id: 43},
%Api.CategorySubcategory{c_id: 2, s_id: 44},
%Api.CategorySubcategory{c_id: 2, s_id: 45},
%Api.CategorySubcategory{c_id: 2, s_id: 46},
%Api.CategorySubcategory{c_id: 2, s_id: 47},
%Api.CategorySubcategory{c_id: 2, s_id: 49},
%Api.CategorySubcategory{c_id: 2, s_id: 50},
%Api.CategorySubcategory{c_id: 2, s_id: 51},
%Api.CategorySubcategory{c_id: 2, s_id: 52},
%Api.CategorySubcategory{c_id: 2, s_id: 53},
%Api.CategorySubcategory{c_id: 2, s_id: 54},
%Api.CategorySubcategory{c_id: 2, s_id: 55},
%Api.CategorySubcategory{c_id: 2, s_id: 56},
%Api.CategorySubcategory{c_id: 2, s_id: 57},
%Api.CategorySubcategory{c_id: 2, s_id: 58},
%Api.CategorySubcategory{c_id: 2, s_id: 59},
%Api.CategorySubcategory{c_id: 2, s_id: 60},
%Api.CategorySubcategory{c_id: 2, s_id: 61},
%Api.CategorySubcategory{c_id: 2, s_id: 62},
%Api.CategorySubcategory{c_id: 2, s_id: 63},
%Api.CategorySubcategory{c_id: 2, s_id: 64},
%Api.CategorySubcategory{c_id: 2, s_id: 65},
%Api.CategorySubcategory{c_id: 2, s_id: 66},
%Api.CategorySubcategory{c_id: 2, s_id: 67},
%Api.CategorySubcategory{c_id: 2, s_id: 68},
%Api.CategorySubcategory{c_id: 2, s_id: 69},
%Api.CategorySubcategory{c_id: 2, s_id: 70},
%Api.CategorySubcategory{c_id: 2, s_id: 71},
%Api.CategorySubcategory{c_id: 2, s_id: 72},
%Api.CategorySubcategory{c_id: 2, s_id: 73},
%Api.CategorySubcategory{c_id: 2, s_id: 74},
]
Enum.each(categorySubcategories, fn (categorySubcategory) -> insert(categorySubcategory) end)
end
def getCategories(conn) do
insertCategories
categories = all Api.Category
conn
|> put_resp_content_type("application/json")
|> send_resp(200, Poison.encode!(%{categories: categories}))
end
def getSubcategories do
Api.Subcategory |> all
end
end
relevant part of router.ex
get "/categories/" do
[controller] = ["repo"]
Api.Repo.getCategories(conn)
end
I browse to localhost:4000/categories and get the error at the top.
output of IO.puts(categories) - it has a lot of duplicated rows but that is another issue lol.
16:59:54.922 [debug] QUERY OK source="categories" db=5.2ms decode=3.7ms
SELECT c0."id", c0."name" FROM "categories" AS c0 []
[%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 1,
name: "Grocery Products"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 2,
name: "Meals"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 3,
name: "Grocery Products"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 4,
name: "Meals"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 5,
name: "Grocery Products"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 6,
name: "Meals"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 7,
name: "Grocery Products"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 8,
name: "Meals"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 9,
name: "Grocery Products"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 10,
name: "Meals"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 11,
name: "Grocery Products"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 12,
name: "Meals"}]
16:59:55.038 [error] #PID<0.340.0> running Api.Router terminated
Server: localhost:4000 (http)
Request: GET /categories
** (exit) an exception was raised:
** (Poison.EncodeError) unable to encode value: {nil, "categories"}
(poison) lib/poison/encoder.ex:383: Poison.Encoder.Any.encode/2
(poison) lib/poison/encoder.ex:227: anonymous fn/4 in Poison.Encoder.Map.encode/3
(poison) lib/poison/encoder.ex:228: Poison.Encoder.Map."-encode/3-lists^foldl/2-0-"/3
(poison) lib/poison/encoder.ex:228: Poison.Encoder.Map.encode/3
(poison) lib/poison/encoder.ex:227: anonymous fn/4 in Poison.Encoder.Map.encode/3
(poison) lib/poison/encoder.ex:228: Poison.Encoder.Map."-encode/3-lists^foldl/2-0-"/3
(poison) lib/poison/encoder.ex:228: Poison.Encoder.Map.encode/3
(poison) lib/poison/encoder.ex:259: anonymous fn/3 in Poison.Encoder.List.encode/3

You need to make a custom implementation of Poison.Encoder for your struct so that it doesn't try to encode the __meta__ field of the struct (which contains a tuple in it which Poison does not handle). The easiest way to do this is to add a #derive to the struct with the names of the fields you want to encode:
defmodule Api.Category do
...
#derive {Poison.Encoder, only: [:id, :name]} # <- add this
schema "categories" do
...
end
...
end

Related

How to extract replies from Facebook comments stored in list of dictionaries?

I'm working with a Facebook scraping, however, I'm having difficulties working with the responses to the comments.
For the collection of comments, this is the code:
import pandas as pd
import facebook_scraper
post_ids = ['1014199301965488']
options = {"comments": True,
"reactors": True,
"allow_extra_requests": True,
}
cookies = "/content/cookies.txt" #it is necessary to generate a Facebook cookie file
replies = []
for post in facebook_scraper.get_posts(post_urls=post_ids, cookies=cookies, options=options):
for p in post['comments_full']:
replies.append(p)
Basically, each comment can have more than one answer. From what I understand, each answer is stored in a list of dictionaries. Here is an example of some replies.
[{'comment_id': '1014587065260045', 'comment_url': 'https://facebook.com/1014587065260045', 'commenter_id': '100002664042251', 'commenter_url': 'https://facebook.com/anderson.ritmoapoesia?fref=nf&rc=p&__tn__=R', 'commenter_name': 'Anderson Ritmoapoesia', 'commenter_meta': None, 'comment_text': 'Boa irmão!\nTmj', 'comment_time': datetime.datetime(2015, 8, 17, 0, 0), 'comment_image': 'https://scontent.xx.fbcdn.net/m1/v/t6/An_UvxJXg9tdnLU3Y5qjPi0200MLilhzPXUgxzGjQzUMaNcmjdZA6anyrngvkdub33NZzZhd51fpCAEzNHFhko5aKRFP5fS1w_lKwYrzcNLupv27.png?_nc_eui2=AeH0Z9O-PPSBg9l8FeLeTyUHMiCX3WNpzi0yIJfdY2nOLeM4yQsYnDi7Fo-bVaW2oRmOKEYPCsTFZnVoJbmO2yOH&ccb=10-5&oh=00_AT-4ep4a5bI4Gf173sbCjcAhS7gahF9vcYuM9GaQwJsI9g&oe=6301E8F9&_nc_sid=55e238', 'comment_reactors': [{'name': 'Marcio J J Tomaz', 'link': 'https://facebook.com/marcioroberto.rodriguestomaz?fref=pb', 'type': 'like'}], 'comment_reactions': {'like': 1}, 'comment_reaction_count': 1}]
[{'comment_id': '1014272461958172', 'comment_url': 'https://facebook.com/1014272461958172', 'commenter_id': '100009587231687', 'commenter_url': 'https://facebook.com/cassia.danyelle.94?fref=nf&rc=p&__tn__=R', 'commenter_name': 'Cassia Danyelle', 'commenter_meta': None, 'comment_text': 'Concordo!', 'comment_time': datetime.datetime(2015, 8, 17, 0, 0), 'comment_image': None, 'comment_reactors': [], 'comment_reactions': None, 'comment_reaction_count': None}, {'comment_id': '1014275711957847', 'comment_url': 'https://facebook.com/1014275711957847', 'commenter_id': '1227694094', 'commenter_url': 'https://facebook.com/marcusvinicius.espiritosanto?fref=nf&rc=p&__tn__=R', 'commenter_name': 'Marcus Vinicius Espirito Santo', 'commenter_meta': None, 'comment_text': 'Concordo Marcão a única observação que faço é: a justiça deveria funcionar sempre dessa forma rápida e precisa, como neste caso.', 'comment_time': datetime.datetime(2015, 8, 17, 0, 0), 'comment_image': 'https://scontent.xx.fbcdn.net/m1/v/t6/An_UvxJXg9tdnLU3Y5qjPi0200MLilhzPXUgxzGjQzUMaNcmjdZA6anyrngvkdub33NZzZhd51fpCAEzNHFhko5aKRFP5fS1w_lKwYrzcNLupv27.png?_nc_eui2=AeH0Z9O-PPSBg9l8FeLeTyUHMiCX3WNpzi0yIJfdY2nOLeM4yQsYnDi7Fo-bVaW2oRmOKEYPCsTFZnVoJbmO2yOH&ccb=10-5&oh=00_AT-4ep4a5bI4Gf173sbCjcAhS7gahF9vcYuM9GaQwJsI9g&oe=6301E8F9&_nc_sid=55e238', 'comment_reactors': [{'name': 'Marcos Alexandre de Souza', 'link': 'https://facebook.com/senseimarcos?fref=pb', 'type': 'like'}], 'comment_reactions': {'like': 1}, 'comment_reaction_count': 1}]
[{'comment_id': '1014367808615304', 'comment_url': 'https://facebook.com/1014367808615304', 'commenter_id': '100005145968202', 'commenter_url': 'https://facebook.com/flavioluis.schnurr?fref=nf&rc=p&__tn__=R', 'commenter_name': 'Flavio Luis Schnurr', 'commenter_meta': None, 'comment_text': 'E porque você não morre ! Quem apoia assassinos também é!', 'comment_time': datetime.datetime(2015, 8, 17, 0, 0), 'comment_image': None, 'comment_reactors': [], 'comment_reactions': None, 'comment_reaction_count': None}]
[{'comment_id': '1014222638629821', 'comment_url': 'https://facebook.com/1014222638629821', 'commenter_id': '100009383732423', 'commenter_url': 'https://facebook.com/profile.php?id=100009383732423&fref=nf&rc=p&__tn__=R', 'commenter_name': 'Anerol Ahnuc', 'commenter_meta': None, 'comment_text': 'Hã?', 'comment_time': datetime.datetime(2015, 8, 17, 0, 0), 'comment_image': 'https://scontent.xx.fbcdn.net/m1/v/t6/An_UvxJXg9tdnLU3Y5qjPi0200MLilhzPXUgxzGjQzUMaNcmjdZA6anyrngvkdub33NZzZhd51fpCAEzNHFhko5aKRFP5fS1w_lKwYrzcNLupv27.png?_nc_eui2=AeH0Z9O-PPSBg9l8FeLeTyUHMiCX3WNpzi0yIJfdY2nOLeM4yQsYnDi7Fo-bVaW2oRmOKEYPCsTFZnVoJbmO2yOH&ccb=10-5&oh=00_AT-4ep4a5bI4Gf173sbCjcAhS7gahF9vcYuM9GaQwJsI9g&oe=6301E8F9&_nc_sid=55e238', 'comment_reactors': [], 'comment_reactions': {'like': 1}, 'comment_reaction_count': 1}, {'comment_id': '1014236578628427', 'comment_url': 'https://facebook.com/1014236578628427', 'commenter_id': '100009383732423', 'commenter_url': 'https://facebook.com/profile.php?id=100009383732423&fref=nf&rc=p&__tn__=R', 'commenter_name': 'Anerol Ahnuc', 'commenter_meta': None, 'comment_text': 'Eu hein?', 'comment_time': datetime.datetime(2015, 8, 17, 0, 0), 'comment_image': None, 'comment_reactors': [], 'comment_reactions': None, 'comment_reaction_count': None}]
[{'comment_id': '1014435731941845', 'comment_url': 'https://facebook.com/1014435731941845', 'commenter_id': '100003779689547', 'commenter_url': 'https://facebook.com/marcia.pimentel.5454?fref=nf&rc=p&__tn__=R', 'commenter_name': 'Márcia Pimentel', 'commenter_meta': None, 'comment_text': 'Não é que sejam defensores Marcondes Martins,sim,eles falam que ele era um ser humano que errou e que podia ter pago de outra maneira,e não com a morte,porque só quem tem direito de tirar a vida das pessoas é Aquele que nos deu... Jesus.', 'comment_time': datetime.datetime(2015, 8, 17, 0, 0), 'comment_image': None, 'comment_reactors': [], 'comment_reactions': None, 'comment_reaction_count': None}, {'comment_id': '1014445965274155', 'comment_url': 'https://facebook.com/1014445965274155', 'commenter_id': '100000515531313', 'commenter_url': 'https://facebook.com/DJ.Marcondes.Martins?fref=nf&rc=p&__tn__=R', 'commenter_name': 'Marcondes Martins', 'commenter_meta': None, 'comment_text': 'Marcia Márcia Pimentel ta teoria é tudo bonitinho. Mas bandidos matam, estupram, humilham pessoas de bem e a justiça ainda protege esses vermes, a sociedade ja está cansada disso.', 'comment_time': datetime.datetime(2015, 8, 17, 0, 0), 'comment_image': None, 'comment_reactors': [], 'comment_reactions': None, 'comment_reaction_count': None}]
Based on the data above, I only need the values for 'comment_text', however, I've never worked with this type of structure. Is it possible to extract each occurrence in 'comment_text'?
Since you're working with a list of dictionaries, I would use a list comprehension to loop the items in the list, and then extract only the key I wanted from each dictionary:
replies.append([reply['comment_text'] for reply in p])
An example of what it would do
p = [{'comment_id': '1014272461958172', 'comment_url': 'https://facebook.com/1014272461958172', 'commenter_id': '100009587231687', 'commenter_url': 'https://facebook.com/cassia.danyelle.94?fref=nf&rc=p&__tn__=R', 'commenter_name': 'Cassia Danyelle', 'commenter_meta': None, 'comment_text': 'Concordo!', 'comment_time': datetime.datetime(2015, 8, 17, 0, 0), 'comment_image': None, 'comment_reactors': [], 'comment_reactions': None, 'comment_reaction_count': None}, {'comment_id': '1014275711957847', 'comment_url': 'https://facebook.com/1014275711957847', 'commenter_id': '1227694094', 'commenter_url': 'https://facebook.com/marcusvinicius.espiritosanto?fref=nf&rc=p&__tn__=R', 'commenter_name': 'Marcus Vinicius Espirito Santo', 'commenter_meta': None, 'comment_text': 'Concordo Marcão a única observação que faço é: a justiça deveria funcionar sempre dessa forma rápida e precisa, como neste caso.', 'comment_time': datetime.datetime(2015, 8, 17, 0, 0), 'comment_image': 'https://scontent.xx.fbcdn.net/m1/v/t6/An_UvxJXg9tdnLU3Y5qjPi0200MLilhzPXUgxzGjQzUMaNcmjdZA6anyrngvkdub33NZzZhd51fpCAEzNHFhko5aKRFP5fS1w_lKwYrzcNLupv27.png?_nc_eui2=AeH0Z9O-PPSBg9l8FeLeTyUHMiCX3WNpzi0yIJfdY2nOLeM4yQsYnDi7Fo-bVaW2oRmOKEYPCsTFZnVoJbmO2yOH&ccb=10-5&oh=00_AT-4ep4a5bI4Gf173sbCjcAhS7gahF9vcYuM9GaQwJsI9g&oe=6301E8F9&_nc_sid=55e238', 'comment_reactors': [{'name': 'Marcos Alexandre de Souza', 'link': 'https://facebook.com/senseimarcos?fref=pb', 'type': 'like'}], 'comment_reactions': {'like': 1}, 'comment_reaction_count': 1}]
print([reply['comment_text'] for reply in p]) # ['Concordo!', 'Concordo Marcão a única observação que faço é: a justiça deveria funcionar sempre dessa forma rápida e precisa, como neste caso.']

Binance API: How do I get the quantity precision of a futures asset?

I want to get the price precision of any futures asset.
What I tried:
client.get_symbol_info(symbol='My Symbol')
But this returns the precision of the Spot and I need the precision of the futures.
So theres this Command:
client.futures_exchange_info()
Which return this:
{'timezone': 'UTC', 'serverTime': 1630437033153, 'futuresType': 'U_MARGINED', 'rateLimits': [{'rateLimitType': 'REQUEST_WEIGHT', 'interval': 'MINUTE', 'intervalNum': 1, 'limit': 2400},
{'rateLimitType': 'ORDERS', 'interval': 'MINUTE', 'intervalNum': 1, 'limit': 1200},
{'rateLimitType': 'ORDERS', 'interval': 'SECOND', 'intervalNum': 10, 'limit': 300}],
'exchangeFilters': [],
'assets': [{'asset': 'USDT', 'marginAvailable': True, 'autoAssetExchange': '-10000'},
{'asset': 'BTC', 'marginAvailable': True, 'autoAssetExchange': '-0.00100000'},
{'asset': 'BNB', 'marginAvailable': True, 'autoAssetExchange': '-10'},
{'asset': 'ETH', 'marginAvailable': True, 'autoAssetExchange': '-5'},
{'asset': 'BUSD', 'marginAvailable': True, 'autoAssetExchange': '-10000'}],
'symbols': [{'symbol': 'BTCUSDT', 'pair': 'BTCUSDT', 'contractType': 'PERPETUAL', 'deliveryDate': 4133404800000, 'onboardDate': 1569398400000, 'status': 'TRADING', 'maintMarginPercent': '2.5000', 'requiredMarginPercent': '5.0000', 'baseAsset': 'BTC', 'quoteAsset': 'USDT', 'marginAsset': 'USDT', 'pricePrecision': 2, 'quantityPrecision': 3, 'baseAssetPrecision': 8, 'quotePrecision': 8, 'underlyingType': 'COIN', 'underlyingSubType': [], 'settlePlan': 0, 'triggerProtect': '0.0500', 'liquidationFee': '0.012000', 'marketTakeBound': '0.05', 'filters': [{'minPrice': '556.72', 'maxPrice': '4529764', 'filterType': 'PRICE_FILTER', 'tickSize': '0.01'}, {'stepSize': '0.001', 'filterType': 'LOT_SIZE', 'maxQty': '1000', 'minQty': '0.001'}, {'stepSize': '0.001', 'filterType': 'MARKET_LOT_SIZE', 'maxQty': '200', 'minQty': '0.001'}, {'limit': 200, 'filterType': 'MAX_NUM_ORDERS'}, {'limit': 10, 'filterType': 'MAX_NUM_ALGO_ORDERS'}, {'notional': '5', 'filterType': 'MIN_NOTIONAL'}, {'multiplierDown': '0.9500', 'multiplierUp': '1.0500', 'multiplierDecimal': '4', 'filterType': 'PERCENT_PRICE'}], 'orderTypes': ['LIMIT', 'MARKET', 'STOP', 'STOP_MARKET', 'TAKE_PROFIT', 'TAKE_PROFIT_MARKET', 'TRAILING_STOP_MARKET'], 'timeInForce': ['GTC', 'IOC', 'FOK', 'GTX']},
{'symbol': 'ETHUSDT', 'pair': 'ETHUSDT', 'contractType': 'PERPETUAL', 'deliveryDate': 4133404800000, 'onboardDate': 1569398400000, 'status': 'TRADING', 'maintMarginPercent': '2.5000', 'requiredMarginPercent': '5.0000', 'baseAsset': 'ETH', 'quoteAsset': 'USDT', 'marginAsset': 'USDT', 'pricePrecision': 2, 'quantityPrecision': 3, 'baseAssetPrecision': 8, 'quotePrecision': 8, 'underlyingType': 'COIN', 'underlyingSubType': [], 'settlePlan': 0, 'triggerProtect': '0.0500', 'liquidationFee': '0.005000', 'marketTakeBound': '0.05', 'filters': [{'minPrice': '39.86', 'maxPrice': '306177', 'filterType': 'PRICE_FILTER', 'tickSize': '0.01'}, {'stepSize': '0.001', 'filterType': 'LOT_SIZE', 'maxQty': '10000', 'minQty': '0.001'}, {'stepSize': '0.001', 'filterType': 'MARKET_LOT_SIZE', 'maxQty': '2000', 'minQty': '0.001'}, {'limit': 200, 'filterType': 'MAX_NUM_ORDERS'}, {'limit': 10, 'filterType': 'MAX_NUM_ALGO_ORDERS'}, {'notional': '5', 'filterType': 'MIN_NOTIONAL'}, {'multiplierDown': '0.9500', 'multiplierUp': '1.0500', 'multiplierDecimal': '4', 'filterType': 'PERCENT_PRICE'}], 'orderTypes': ['LIMIT', 'MARKET', 'STOP', 'STOP_MARKET', 'TAKE_PROFIT', 'TAKE_PROFIT_MARKET', 'TRAILING_STOP_MARKET'], 'timeInForce': ['GTC', 'IOC', 'FOK', 'GTX']}...
and so on.
I need to access the Value of 'quantityPrecision':.
Is there a way to like filter this list for the symbol value like 'BTCUSDT' and then return the Value of 'quantityPrecision':?
Thanks in Advance for any help.
info = client.futures_exchange_info()
def get_precision(symbol):
for x in info['symbols']:
if x['symbol'] == symbol:
return x['quantityPrecision']
print(get_precision('LTCUSDT'))
async function getLimits(asset) {
var filtered = await client.futures_exchange_info()
return Object.values( filtered.symbols).filter(O => O.symbol===asset)[0]
}
getLimits("BTCUSDT")

Get value in Nested Dictionary Python Odoo

I have a problem...again. It is related to my previous question in Cron. I've got JSON value and I want to enter it in database. I need help in getting values in this nested dict. Plz help!
JSON
{'folders': [{'id': 94, 'name': 'Retargeting January 2021', 'totalBlacklisted': 606, 'uniqueSubscribers': 19988, 'totalSubscribers': 19382},
{'id': 90, 'name': 'Leads', 'totalBlacklisted': 0, 'uniqueSubscribers': 0, 'totalSubscribers': 0},
{'id': 84, 'name': 'Retargeting Year End', 'totalBlacklisted': 1367, 'uniqueSubscribers': 18847, 'totalSubscribers': 17480},
{'id': 79, 'name': 'CRM Folder', 'totalBlacklisted': 0, 'uniqueSubscribers': 3, 'totalSubscribers': 3},
{'id': 56, 'name': 'Curioo P', 'totalBlacklisted': 282, 'uniqueSubscribers': 3279, 'totalSubscribers': 2997}]}
Python
res = simplejson.loads(response.text)
self.env['get.folders'].create({
'id' : self.id,
'name': res['name'],
'email_blacklist': res['totalBlacklisted'],
'email_subscribers': res['totalSubscribers'],
'unique_subscribers': res['uniqueSubscribers'],
'foldersId': res['id'],
})
EDIT
At last it works. I try to spell out the values and I don't know how but it works this way. Thanks #Jack Dane for your help.
for folder in folders.get("folders"):
names = folder['name']
ids = folder['id']
blacklist = folder['totalBlacklisted']
subscribe = folder['totalSubscribers']
unique = folder['uniqueSubscribers']
self.env['sendinblue.get_folders'].create({
# 'id' : folder['id'],
'name_folder': names,
'email_blacklist': blacklist,
'email_subscribers': subscribe,
'unique_subscribers': unique,
'foldersId': ids,
})
You can loop through the folders using a foreach loop call the create function:
folders = {'folders': [{'id': 94, 'name': 'Retargeting January 2021', 'totalBlacklisted': 606, 'uniqueSubscribers': 19988, 'totalSubscribers': 19382},
{'id': 90, 'name': 'Leads', 'totalBlacklisted': 0, 'uniqueSubscribers': 0, 'totalSubscribers': 0},
{'id': 84, 'name': 'Retargeting Year End', 'totalBlacklisted': 1367, 'uniqueSubscribers': 18847, 'totalSubscribers': 17480},
{'id': 79, 'name': 'CRM Folder', 'totalBlacklisted': 0, 'uniqueSubscribers': 3, 'totalSubscribers': 3},
{'id': 56, 'name': 'Curioo P', 'totalBlacklisted': 282, 'uniqueSubscribers': 3279, 'totalSubscribers': 2997}]}
for folder in folders.get("folders"):
self.env['get.folders'].create({
'id' : self.id,
'name': folder['name'],
'email_blacklist': folder['totalBlacklisted'],
'email_subscribers': folder['totalSubscribers'],
'unique_subscribers': folder['uniqueSubscribers'],
'foldersId': folder['id'],
})
In my case, I have used folders as the variable which will be returned as a JSON.
If you need any clarification let me know,
Thanks,

How i can make a distinct in leftJoin using adonis/node.js?

I'm trying to make a distinct in a leftJoin, but the .distinct() seems not work for my context.
I have this query:
const questions = Database
.query()
.select('book_unit_question.*')
.select('book_unit.unit')
.select('book_unit.sequence')
.select('books.id as book_id')
.select('book_unit_question_option.description as correct_answer_description_id')
.select('users.username')
.from('book_unit_question')
.leftJoin('book_unit_question_option', 'book_unit_question.id', 'book_unit_question_option.book_unit_question_id')
.distinct('book_unit_question.id')
.innerJoin('book_unit', 'book_unit.id', 'book_unit_question.book_unit_id')
.innerJoin('books', 'books.id', 'book_unit.book_id')
.innerJoin('users', 'book_unit_question.user_id', 'users.id')
.where('books.id', '=', request.params.id)
But when i get my results, i have repetead book_unit_question.id :
0: {id: 11, book_unit_id: 2, question_form: "Texto", option_form: "Texto",…}
1: {id: 11, book_unit_id: 2, question_form: "Texto", option_form: "Texto",…}
2: {id: 11, book_unit_id: 2, question_form: "Texto", option_form: "Texto",…}
3: {id: 12, book_unit_id: 2, question_form: "Texto", option_form: "Texto", type_answer: "Aberta",…}
I need only:
0: {id: 11, book_unit_id: 2, question_form: "Texto", option_form: "Texto",…}
1: {id: 12, book_unit_id: 2, question_form: "Texto", option_form: "Texto", type_answer: "Aberta",…}
Try to use distinct() without parameters:
const questions = Database
.from('book_unit_question')
.select('book_unit_question.*', 'book_unit.unit', 'book_unit.sequence', 'books.id as book_id', 'book_unit_question_option.description as correct_answer_description_id', 'users.username')
.distinct()
.leftJoin('book_unit_question', 'book_unit_question.id', '=', 'book_unit_question_option.book_unit_question_id')
.join('book_unit', 'book_unit.id', '=', 'book_unit_question.book_unit_id')
.join('books', '=', 'books.id', 'book_unit.book_id')
.join('users', '=', 'book_unit_question.user_id', 'users.id')
.where('books.id', '=', request.params.id);
Docs here

pass array of arrays from routes to view node.js

I am trying to pass an array of arrays from routes to view page. My data that I am trying to pass is :
[
[10, 10],
[20, 50],
[30, 120],
[40, 80],
[50, 90],
[60, 50],
[70, 70],
[80, 90],
[90, 150],
[100, 50],
[110, 40],
[120, 70],
[130, 20],
[140, 40],
[200, 30]
]
I am getting it in below format:
["10,10,20,50,30,120,40,80,50,90,60,50,70,70,80,90,90,150,100,50,110,40,120,70,130,20,140,40,200,30"]
but I need it in the same format I am sending.
My index.js(routes file) is:
router.get('/', function(req, res, next) {
var dataset = [
[10, 10],
[20, 50],
[30, 120],
[40, 80],
[50, 90],
[60, 50],
[70, 70],
[80, 90],
[90, 150],
[100, 50],
[110, 40],
[120, 70],
[130, 20],
[140, 40],
[200, 30]
];
console.log(dataset);
res.render('index',{"data" : [dataset]});
});
module.exports = router;
and in my view file, I am trying to get it like:
<div class="hold_data" data-info={{data}}></div>
Please suggest if anyone knows how this can be achieved. Thanks in advance :)
Try JSON.stringify as below -
res.render('index',{"data" : JSON.stringify(dataset)});
Hope this helps.

Resources