How to add fields in MongoDb document which already exist? - python

I'm trying to get some POST requests using Postman to MongoDb and everything works well.
Following is the code:
def add_npo():
add_new_npo = mongo.db.npos
name = request.json['name']
description = request.json['description']
category = request.json['category']
status = request.json["status"]
npo_id = add_new_npo.insert({'name': name, 'description':
description, 'category': category,'status': status})
new_npo = add_new_npo.find_one({'_id': npo_id })
output = {'name': new_npo["name"], 'description':
new_npo["description"], 'category': new_npo["category"], 'status':
new_npo["status"]}
return jsonify({'result' : output})
But how can I add new fields on the document without assigning them in advance?

You can add new fields on the document by update operation.
For example,
db.col.update({your filter}, {"$set": {"newField": newFieldValue}})

Related

Random value from cloud datastore

I'm writing a python program to save and retrieve a customer data in cloud datastore. My entity looks like below:
entity.update({
'customerId': args['customerId'],
'name': args['name'],
'email': args['email'],
'city': args['city'],
'mobile': args['mobile']
})
datastore_client.put(entity)
I'm successfully saving the data. Now, I want to retrieve a random email id from the a record. I have written the below code:
def get_customer():
query = datastore_client.query(kind='CustomerKind')
results = list(query.fetch())
chosen_customer = random.choice(results)
print(chosen_customer)
But instead getting only one random email id, I'm getting the entire row like this:
<Entity('CustomerKind', 6206716152643584) {'customerId': '103', 'city': 'bhubaneswar', 'name': 'Amit', 'email': 'amit#gmail.com', 'mobile': '7879546732'}>
Can anyone suggest how can I get only 'email': 'amit#gmail.com' ? I'm new to datastore.
When using
query = datastore_client.query(kind='CustomerKind')
results = list(query.fetch())
you are retrieving all the properties from all the entities that will be returned.
Instead, you can use a projection query, which allows you to retrieve only the specified properties from the entities:
query = client.query(kind="CustomerKind")
query.projection = ["email"]
results = list(query.fetch())
Using projection queries is recommended for cases like this, in which you only need some properties as they reduce cost and latency.

Create batch records with Odoo create method

I am trying to create multiple invoices from an array of dictionaries with the create values in odoo13.
Creating one record at a time is okay but when I try with the batch record I get the error can't adapt to type dict
I have tried looping through the array and create a record for each item in it but this error persists.
I am currently checking on the #api.model_create_multi decorator but haven't grasped it yet fully.
What I want is that for each line in the visa_line(same as order line), to create an invoice from that. Some fields in creating an invoice are missing but that should not be the issue.
When I print the record, in the final function, it prints the duct with values correctly.
Here is my code, thank you in advance
def _prepare_invoice(self):
journal = self.env['account.move'].with_context(
default_type='out_invoice')._get_default_journal()
invoice_vals = {
'type': 'out_invoice',
'invoice_user_id': self.csa_id and self.csa_id.id,
'source_id': self.id,
'journal_id': journal.id,
'state': 'draft',
'invoice_date': self.date,
'invoice_line_ids': []
}
return invoice_vals
def prepare_create_invoice(self):
invoice_val_dicts = []
invoice_val_list = self._prepare_invoice()
for line in self.visa_line:
invoice_val_list['invoice_partner_bank_id'] = line.partner_id.bank_ids[:1].id,
invoice_val_list['invoice_line_ids'] = [0, 0, {
'name': line.code,
'account_id': 1,
'quantity': 1,
'price_unit': line.amount,
}]
invoice_val_dicts.append(invoice_val_list)
return invoice_val_dicts
#api.model_create_multi
def create_invoice(self, invoices_dict):
invoices_dict = self.prepare_create_invoice()
for record in invoices_dict:
print(record)
records = self.env['account.move'].create(record)
I fixed this issue by explicitly type fixing the record with duct. Using a normal create method without the #api.model_create_multi.
def create_invoice(self):
invoices_dict = self.prepare_create_invoice()
for record in invoices_dict:
records = self.env['account.move'].create(dict(record))

Why is the HITBTC V2 REST API returning a 2001 error (Incorrect Pair)?

I'm trying to place an order using V2 of the HITBTC API (docs here). I'm trying to place an order via a POST request, and everything is fine authorization wise, but upon placing the order, the following function returns what the server is sending back, which is the following JSON:
{'error': {'code': 2001, 'message': 'Symbol not found', 'description': 'Try get /api/2/public/symbol, to get list of all available symbols.'}}
My issue arises with the fact that I'm passing the pair I wish to order in the format that's specified by this call for the symbols, which returns JSON like the following:
{"id":"NOAHBTC","baseCurrency":"NOAH","quoteCurrency":"BTC","quantityIncrement":"1000","tickSize":"0.000000001","takeLiquidityRate":"0.001","provideLiquidityRate":"-0.0001","feeCurrency":"BTC"}
I'm passing a string formatted exactly as 'id' is formatted.
def HITBTCorder(pair, side, quantity, price, session):
'''
Creates an order on HITBTC, returns status (filled or not filled)
Side: 'buy' or 'sell'
'''
orderData = json.dumps({'symbol': pair, 'side': side, 'quantity': quantity, 'price': price})
print(orderData)
response = session.post('https://api.hitbtc.com/api/2/order', data = orderData)
responseDict = json.loads(response.text)
return responseDict
The code I'm running looks like this:
session = requests.session()
session.auth = ('APIPUBLIC', 'APISECRET')
response = trade.HITBTCorder("NOAHBTC", 'buy', 1000, tickers.HITBTCprice("NOAHBTC"), session)
Any idea how to get this working?
You may replace
orderData = json.dumps({'symbol': pair, 'side': side, 'quantity': quantity, 'price': price})
to:
orderData = json.dumps({'symbol': pair.lower(), 'side': side, 'quantity': quantity, 'price': price})
because symbol is required to be sent as lowercase.
Data needs to be URL encoded in request body (quantity=1&symbol=ETHBTC...) not JSON to be accepted by server, hope it helps :)
import urllib.parse as parse;
data = parse.urlencode(yourparamsasdict);

How to post with categories to Wordpress using WP REST API?

I created this small script to create wordpres posts, using Basic Auth, and it works. The problem is when I try to assign multiple categories to a post.
The reference is pretty vague. It says that the categories field must be an array. But it doesn't specify if it should be an array of category objects or if the id of these categories must be passed to the field.
https://developer.wordpress.org/rest-api/reference/posts/#schema-categories
So I tried to make it fail so I can get more info from an exception message. The exception message says something like categories[0] is not an integer So I tried with a list of integers. And then, it works. But only one category is assigned, only the last category in the list.
So, How do I add more categories to a post ?
N1: Categories with id's 13 and 16 actually exists in my wordpress install.
N2: I know that I could create a draft, then create new requests to create categories then, use an update post endpoint to assign categories to posts... But in theory, should be possible to pass multiple categories just creating the post, since its in the reference xd
N3: I don't care about security. It is not a requirement.
import base64
import requests
r = requests.session()
wp_host = 'wphost.dev'
wp_username = 'FIXME'
wp_password = 'FIXME'
# BUILD BASIC AUTH STRING
basic_auth = str(
base64.b64encode('{user}:{passwd}'.format(
user=wp_username,
passwd=wp_password
).encode()
), 'utf-8')
# PARAMETERS TO POST REQUEST
p = {
'url': 'http://{wp_host}/wp-json/wp/v2/posts'.format(wp_host=wp_host),
'headers': {'Authorization': 'Basic {basic_auth}'.format(basic_auth=basic_auth)},
'data': {
'title': 'My title',
'content': 'My content',
'categories': [13, 16],
'status': 'publish',
},
}
# THE REQUEST ITSELF
r = r.post(url=p['url'], headers=p['headers'], data=p['data'])
# Output
print(r.content)
# ... "categories":[16],"tags":[] ...
The WP API reference is misleading.
Actually comma separated string with categories IDs is expected:
data: {
...
categories: "162,224"
...
}

How to add multiple entries to Mongodb document at once using MongoEngine in Flask?

How can I add several entries to a document at once in Flask using MongoEngine/Flask-MongoEngine?
I tried to iterate over the dictionary that contains my entries. I simplified the example a bit, but originally the data is a RSS file that my Wordpress spits out and that I parsed via feedparser.
But the problem obviously is that I cannot dynamically generate variables that hold my entries before being saved to the database.
Here is what I tried so far.
How can I add the entries to my MongoDB database in bulk?
# model
class Entry(db.Document):
created_at = db.DateTimeField(
default=datetime.datetime.now, required=True),
title = db.StringField(max_length=255, required=True)
link = db.StringField(required=True)
# dictionary with entries
e = {'entries': [{'title': u'title1',
'link': u'http://www.me.com'
},
{'title': u'title2',
'link': u'http://www.me.com/link/'
}
]
}
# multiple entries via views
i = 0
while i<len(e['entries']):
post[i] = Entry(title=e['entries'][i]['title'], link=e['entries'][i]['title'])
post[i].save();
i += 1
Edit 1:
I thought about skipping the variables alltogether and translate the dictionary to the form that mongoengine can understand.
Because when I create a list manually, I can enter them in bulk into MongoDB:
newList = [RSSPost(title="test1", link="http://www.google.de"),
RSSPost(title="test2", link="http://www.test2.com")]
RSSPost.objects.insert(newList)
This works, but I could not translate it completely to my problem.
I tried
f = []
for x in e['entries']:
f.append("insert " + x['link'] + " and " + x['title'])
But as you see I could not recreate the list I need.
How to do it correctly?
# dictionary with entries
e = {'entries': [{'title': u'title1',
'link': u'http://www.me.com'
},
{'title': u'title2',
'link': u'http://www.me.com/link/'
}
]
}
How is your data/case different from the examples you posted? As long as I'm not missing something you should be able to instantiate Entry objects like:
entries = []
for entry in e['entries']:
new_entry = Entry(title=entry['title'], link=entry['link'])
entries.append(new_entry)
Entry.objects.insert(entries)
Quick and easy way:
for i in e['entries']:
new_e = Entry(**i)
new_e.save()

Categories