I have written the following code in Python to use ElasticSearch for performing search on the data:
def main():
start = (time.time())
es = Elasticsearch()
es.indices.create(index='bhar',body = {
"settings":{
"analysis":{
"analyzer":{
"my_stop_analyzer":{
"type":"custom",
"tokenizer":"standard",
"filter":["english_possessive_stemmer","lowercase","english_stop","english_stemmer"]
}
},
"filter":{
"english_stop":{
"type":"stop",
"stopwords":"_english_"
},
"english_stemmer":{
"type":"stemmer",
"name":"english"
},
"english_possessive_stemmer": {
"type": "stemmer",
"language": "possessive_english"
}
}
}
},
"mappings":{
"my_type":{
"properties":{
"test": {
"type":"text",
"analyzer" : "my_stop_analyzer"
}
}
}
}
})
data = {"rid":"1","test": "This data BHX1 Pick Tower extension"}
res = es.index(index='bhar',doc_type='news',id=1,body=data,refresh=True)
query='pick tower'
match = es.search(index="bhar",body = {
"query": {
"match":{
"test":{
"query":query.replace('|',' '),
"operator" :"AND"
}
}
}
}
)
if match['hits']['total']:
print(match['hits']['hits'][0]['_source'])
if __name__ == '__main__':
main()
When I execute this code I get the following output:
PUT http://localhost:9200/bhar [status:400 request:0.027s]
{'rid': '1', 'test': 'This data BHX1 Pick Tower extension'}
How do I control the PUT statement on the screen? Maybe send it to a log file or just not print it on the screen. Any thoughts? Thank you for reading.
Add the following line before executing the elastic search query, then the POST response wont be logged into the log files,
logging.getLogger('elasticsearch').setLevel(logging.ERROR)
The line you see being printed on screen is due to the following logger.info() call in connection/base.py:
def log_request_success(self, method, full_url, path, body, status_code, response, duration):
...
logger.info(
'%s %s [status:%s request:%.3fs]', method, full_url,
status_code, duration
)
If you don't want it to be printed out you simply need to run your code with the switch --logging-level=WARN
Related
I'm testing Django/Graphene to see if it can fulfill what I need, but I'm getting trouble in unit testing.
I'm using the in-memory SQLite db, with the following code (tests.py):
import json
from graphene_django.utils.testing import GraphQLTestCase
from graphene.test import Client
from users.schema import UserType
class APITestCase(GraphQLTestCase):
def test01_query_users(self):
print("Running test01_query_users")
response = self.query(
'''
query {
users {
id
username
email
}
}
'''
)
print (response)
content = json.loads(response.content)
self.assertResponseNoErrors(response)
print (content)
assert content == {
"data": {
"users": []
}
}
def test02_mutation_addUser(self):
print("Running test02_mutation_addUser")
response = self.query(
'''
mutation {
createUser (username: "testuser", email: "testemail#testserver.com", password: "123456") {
user {
id
username
email
}
}
}
'''
)
print (response)
content = json.loads(response.content)
self.assertResponseNoErrors(response)
print (content)
assert content == {
"data": {
"createUser": {
"user": {
"id": "1",
"username": "testuser",
"email": "testemail#testserver.com"
}
}
}
}
def test03_mutation_addUser(self):
print("Running test03_mutation_addUser")
response = self.query(
'''
mutation {
createUser (username: "testuser2", email: "testemail2#testserver.com", password: "123456") {
user {
id
username
email
}
}
}
'''
)
print (response)
content = json.loads(response.content)
self.assertResponseNoErrors(response)
print (content)
assert content == {
"data": {
"createUser": {
"user": {
"id": "2",
"username": "testuser2",
"email": "testemail2#testserver.com"
}
}
}
}
def test04_query_users(self):
print("Running test04_query_users")
response = self.query(
'''
query {
users {
id
username
email
}
}
'''
)
print (response)
content = json.loads(response.content)
self.assertResponseNoErrors(response)
print (content)
assert content == {
"data": {
"users": []
}
}
The test output is as follows:
Using existing test database for alias 'default'...
System check identified no issues (0 silenced).
Running test01_query_users
<HttpResponse status_code=200, "application/json">
{'data': {'users': []}}
.Running test02_mutation_addUser
<HttpResponse status_code=200, "application/json">
{'data': {'createUser': {'user': {'id': '1', 'username': 'testuser', 'email': 'testemail#testserver.com'}}}}
.Running test03_mutation_addUser
<HttpResponse status_code=200, "application/json">
{'data': {'createUser': {'user': {'id': '1', 'username': 'testuser2', 'email': 'testemail2#testserver.com'}}}}
FRunning test04_query_users
<HttpResponse status_code=200, "application/json">
{'data': {'users': []}}
.
======================================================================
FAIL: test03_mutation_addUser (polls.tests.tests.APITestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\myuser\Projects\Python\virtual-environments\myproject\tests\tests.py", line 89, in test03_mutation_addUser
assert content == {
AssertionError
----------------------------------------------------------------------
Ran 4 tests in 0.980s
FAILED (failures=1)
It runs first test just ok, then the 2nd one ok, adding a user. When it runs the 3rd it returns a different user with the same ID of the previous one, as if the previous mutation's results was wiped out from the DB, failing because the expected ID (2) is not met. When the 4th test is executed it shows the DB has 0 users. The expected result should be a DB with two different users.
Why it seems to wipe the DB after each test? What am I doing wrong? When I pass --keepdb it doesn't store the DB anywhere.
The tests must be isolated from each other, and they are by default.
Django wraps every test in a transaction that is rolled back after the test executes, so the data is not visible outside that test method. You should neither rely on any other test side-effects, nor on the order of their execution (i.e. tests can be run in parallel).
So, you have to set up the test data for test04_query_users specifically inside this method. Create some users via i.e. User.objects.create() or some library like Factory Boy and then query and assert for them.
I'm trying to convert my python code to flutter, but unable to do so. Trying to perform put request to update data on the website. Here is my original put request written in python.
import requests
url = "https://my.website.com/api/request/12"
headers = {"user_key":"kfrrt-000234-as12321-1h58dm66a"}
input_data = '''{
"request": {
"comment": "New comment",
"status": {
"request_status": "Open"
}
}
}'''
data = {'input_data': input_data}
response = requests.put(url,headers=headers,data=data,verify=False)
What I have so far in flutter :
postTaskInfo()async{
var jsonMP= {'request": {"comment": "New comment","status": {"request_status": "Open"}}'};
String jsonString= jsonEncode(jsonMP);
var url = 'https://my.website.com/api/request/12';
await http.put(url, body: jsonString, headers: {"user_key":"kfrrt-000234-as12321-1h58dm66a"} ).then((response){
setState(() {
print(response.body);
});
});
}
I get an error " Unhandled Exception: Converting object to an encodable object failed: Instance of '_CompactLinkedHashSet
Thank you !
The problem occurs due to jsonEncoding failed to encode non-json data to string, so correct the jsonMP variable.
yours:
var jsonMP= {'request": {"comment": "New comment","status": {"request_status": "Open"}}'};
Should be in the form of
var jsonMP = {
"request": {
"comment": "New comment",
"status": {"request_status": "Open"}
}
};
I have an existing worksheet with an existing NamedRange for it and I would like to call the batch_update method of the API to protect that range from being edited by anyone other than the user that makes the batch_update call.
I have seen an example on how to add protected ranges via a new range definition, but not from an existing NamedRange.
I know I need to send the addProtectedRangeResponse request. Can I define the request body with a Sheetname!NamedRange notation?
this_range = worksheet_name + "!" + nrange
batch_update_spreadsheet_request_body = {
'requests': [
{
"addProtectedRange": {
"protectedRange": {
"range": {
"name": this_range,
},
"description": "Protecting xyz",
"warningOnly": False
}
}
}
],
}
EDIT: Given #Tanaike feedback, I adapted the call to something like:
body = {
"requests": [
{
"addProtectedRange": {
"protectedRange": {
"namedRangeId": namedRangeId,
"description": "Protecting via gsheets_manager",
"warningOnly": False,
"requestingUserCanEdit": False
}
}
}
]
}
res2 = service.spreadsheets().batchUpdate(spreadsheetId=ssId, body=body).execute()
print(res2)
But although it lists the new protections, it still lists 5 different users (all of them) as editors. If I try to manually edit the protection added by my gsheets_manager script, it complains that the range is invalid:
Interestingly, it seems to ignore the requestUserCanEdit flag according to the returning message:
{u'spreadsheetId': u'NNNNNNNNNNNNNNNNNNNNNNNNNNNN', u'replies': [{u'addProtectedRange': {u'protectedRange': {u'requestingUserCanEdit': True, u'description': u'Protecting via gsheets_manager', u'namedRangeId': u'1793914032', u'editors': {}, u'protectedRangeId': 2012740267, u'range': {u'endColumnIndex': 1, u'sheetId': 1196959832, u'startColumnIndex': 0}}}}]}
Any ideas?
How about using namedRangeId for your situation? The flow of the sample script is as follows.
Retrieve namedRangeId using spreadsheets().get of Sheets API.
Set a protected range using namedRangeId using spreadsheets().batchUpdate of Sheets API.
Sample script:
nrange = "### name ###"
ssId = "### spreadsheetId ###"
res1 = service.spreadsheets().get(spreadsheetId=ssId, fields="namedRanges").execute()
namedRangeId = ""
for e in res1['namedRanges']:
if e['name'] == nrange:
namedRangeId = e['namedRangeId']
break
body = {
"requests": [
{
"addProtectedRange": {
"protectedRange": {
"namedRangeId": namedRangeId,
"description": "Protecting xyz",
"warningOnly": False
}
}
}
]
}
res2 = service.spreadsheets().batchUpdate(spreadsheetId=ssId, body=body).execute()
print(res2)
Note:
This script supposes that Sheets API can be used for your environment.
This is a simple sample script. So please modify it to your situation.
References:
ProtectedRange
Named and Protected Ranges
If this was not what you want, I'm sorry.
Edit:
In my above answer, I modified your script using your settings. If you want to protect the named range, please modify body as follows.
Modified body
body = {
"requests": [
{
"addProtectedRange": {
"protectedRange": {
"namedRangeId": namedRangeId,
"description": "Protecting xyz",
"warningOnly": False,
"editors": {"users": ["### your email address ###"]}, # Added
}
}
}
]
}
By this, the named range can be modified by only you. I'm using such settings and I confirm that it works in my environment. But if in your situation, this didn't work, I'm sorry.
TL;DR:
Confused on how to parse following JSON response and get the value of [status of 12345 of dynamicValue_GGG of payload] in this case.
Full question:
I get the following as (sanitized) response upon hitting a REST API via Python code below:
response = requests.request("POST", url, data=payload,
headers=headers).json()
{
"payload": {
"name": "asdasdasdasd",
"dynamicValue_GGG": {
"12345": {
"model": "asad",
"status": "active",
"subModel1": {
"dynamicValue_67890": {
"model": "qwerty",
"status": "active"
},
"subModel2": {
"dynamicValue_33445": {
"model": "gghjjj",
"status": "active"
},
"subModel3": {
"dynamicValue_66778": {
"model": "tyutyu",
"status": "active"
}
}
}
},
"date": "2016-02-04"
},
"design": "asdasdWWWsaasdasQ"
}
If I do a type(response['payload']), it gives me 'dict'.
Now, I'm trying to parse the response above and fetch certain keys and values out of it. The problem is that I'm not able to iterate through using "index" and rather have to specify the "key", but then the response has certain "keys" that are dynamically generated and sent over. For instance, the keys called "dynamicValue_GGG", "dynamicValue_66778" etc are not static unlike the "status" key.
I can successfully parse by mentioning like:
print response['payload']['dynamicValue_GGG']['12345'][status]
in which case I get the expected output = 'active'.
However, since I have no control on 'dynamicValue_GGG', it would work only if I can specify something like this instead:
print response['payload'][0][0][status]
But the above line gives me error: " KeyError: 0 " when the python code is executed.
Is there someway in which I can use the power of both keys as well as index together in this case?
The order of values in a dictionary in Python are random, so you cannot use indexing. You'll have to iterate over all elements, potentially recursive, and test to see if it's the thing you're looking for. For example:
def find_submodels(your_dict):
for item_key, item_values in your_dict.items():
if 'status' in item_values:
print item_key, item_values['status']
if type(item_values) == dict:
find_submodels(item_values)
find_submodels(your_dict)
Which would output:
12345 active
dynamicValue_67890 active
dynamicValue_66778 active
dynamicValue_33445 active
I'm trying to create a wave robot, and I have the basic stuff working. I'm trying to create a new blip with help text when someone types #help but for some reason it doesnt create it. I'm getting no errors in the log console, and I'm seeing the info log 'in #log'
def OnBlipSubmitted(properties, context):
# Get the blip that was just submitted.
blip = context.GetBlipById(properties['blipId'])
text = blip.GetDocument().GetText()
if text.startswith('#help') == True:
logging.info('in #help')
blip.CreateChild().GetDocument().SetText('help text')
if it just started working, I have two suggestions...
-->Have you been updating the Robot Version in the constructor? You should change the values as you update changes so that the caches can be updated.
if __name__ == '__main__':
myRobot = robot.Robot('waverobotdev',
image_url = baseurl + 'assets/wave_robot_icon.png',
version = '61', # <-------------HERE
profile_url = baseurl)
-->The server connection between Wave and AppSpot has recently been extremely variable. Sometimes it takes 10+ minutes for the AppSpot server to receive my event, othertimes a few seconds. Verify you're receiving the events you expect.
Edit:
The code you provided looks good, so I wouldn't expect you're doing anything wrong in that respect.
Have you tried using Append() instead of SetText()? That's what I'd do in my C# API - I haven't used the Python API, but I'd imagine it's similar. Here's a sample from my demo robot:
protected override void OnBlipSubmitted(IEvent e)
{
if (e.Blip.Document.Text.Contains("robot"))
{
IBlip blip = e.Blip.CreateChild();
ITextView textView = blip.Document;
textView.Append("Are you talking to me?");
}
}
That works fine.
EDIT: Here's the resulting JSON from the above code:
{
"javaClass": "com.google.wave.api.impl.OperationMessageBundle",
"version": "173784133",
"operations": {
"javaClass": "java.util.ArrayList",
"list": [
{
"javaClass": "com.google.wave.api.impl.OperationImpl",
"type": "BLIP_CREATE_CHILD",
"waveId": "googlewave.com!w+PHAstGbKC",
"waveletId": "googlewave.com!conv+root",
"blipId": "b+Iw_Xw7FCC",
"index": -1,
"property": {
"javaClass": "com.google.wave.api.impl.BlipData",
"annotations": {
"javaClass": "java.util.ArrayList",
"list": []
},
"lastModifiedTime": -1,
"contributors": {
"javaClass": "java.util.ArrayList",
"list": []
},
"waveId": "googlewave.com!w+PHAstGbKC",
"waveletId": "googlewave.com!conv+root",
"version": -1,
"parentBlipId": null,
"creator": null,
"content": "\nAre you talking to me?",
"blipId": "410621dc-d7a1-4be5-876c-0a9d313858bb",
"elements": {
"map": {},
"javaClass": "java.util.HashMap"
},
"childBlipIds": {
"javaClass": "java.util.ArrayList",
"list": []
}
}
},
{
"javaClass": "com.google.wave.api.impl.OperationImpl",
"type": "DOCUMENT_APPEND",
"waveId": "googlewave.com!w+PHAstGbKC",
"waveletId": "googlewave.com!conv+root",
"blipId": "410621dc-d7a1-4be5-876c-0a9d313858bb",
"index": 0,
"property": "Are you talking to me?"
}
]
}
}
How does that compare with the JSON which comes out of your robot?
For some reason it just started working. I think the google wave is spotty.