2

I want to use Python in Elasticsearch. So I wrote an Authentication code in Python for Elasticsearch. But I'm getting the error "TypeError: 'Session' object is not callable". Here's the code:

import requests
from requests import Session
from requests.auth import HTTPBasicAuth
uname = 'elastic'
pswd = 'elastic'
session = requests.Session()
session.auth = HTTPBasicAuth(uname, pswd)
res = requests.get('http://localhost:9200',auth=session)
print(res.content)

Where am I going wrong?

2
  • 1
    Why torture yourself with requests when there are better wrapper around. There are Pyelasticsearch and elasticsearch for python, Commented May 16, 2018 at 9:53
  • May you please add requests as tag to your question? Commented May 16, 2018 at 13:09

7 Answers 7

6

Instead of sessions you can directly use following method to connect to elasticsearch server:

import requests
from requests.auth import HTTPBasicAuth 
from pprint import pprint 

username = 'elastic'
password = 'elastic'

response = requests.get('http://localhost:9200', auth = HTTPBasicAuth(username, password))

pprint(response.content)
Sign up to request clarification or add additional context in comments.

Comments

1

Is there any reason why you wouldn't use the elasticsearch python client library.

from elasticsearch import Elasticsearch

# you can use RFC-1738 to specify the url
es = Elasticsearch(['https://user:secret@localhost:443'])

# ... or specify common parameters as kwargs

es = Elasticsearch(
    ['localhost', 'otherhost'],
    http_auth=('user', 'secret'),
    scheme="https",
    port=443,
)

# SSL client authentication using client_cert and client_key

from ssl import create_default_context

context = create_default_context(cafile="path/to/cert.pem")
es = Elasticsearch(
    ['localhost', 'otherhost'],
    http_auth=('user', 'secret'),
    scheme="https",
    port=443,
    ssl_context=context,
)

https://elasticsearch-py.readthedocs.io/en/master/index.html

Once you have the elasticsearch object it is easy to query your index

res = es.get(index="test-index", doc_type='tweet')
print(res['_source'])

Comments

1

I would recommend using the elasticsearch library to connect.

Here is an example:

from elasticsearch import Elasticsearch
es = Elasticsearch(['hostname:port'],http_auth=('username','password'))
#check if it exists...
if es.exists(index="test",doc_type="test",id="1234"):
    es.update(index="test",doc_type="test",id="1234",body{"doc": {"hi":"data"}})
else:
    es.create(index="test",doc_type="test",id="1234",body={"hi":"data"})

Comments

0

As per documentation http://docs.python-requests.org/en/master/user/authentication/

remove the session object and try this out

requests.get('url', auth=HTTPBasicAuth('user', 'pass'))

3 Comments

Thanks for the help. I made this change y'day & the code ran. But now when I try it again it is giving me some error. Since I'm very new to Python & Elasticsearch, I can't get what is the error. This is the error: ConnectionError: HTTPConnectionPool(host='localhost', port=9200): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x0000023B52C0FE10>: Failed to establish a new connection: [WinError 10061] No connection could be made because the target machine actively refused it',)). How do I resolve this?
I guess, the error says Max retries exceeded with url. Check wheather the API call have some limit per day or something like that. It may occurs because of that also
I suggest you to use native elasticsearch api in python. refer this elasticsearch-py.readthedocs.io/en/master
0

If you want to use Session object, first let's clarify what is it for:

The Session object allows you to persist certain parameters across requests.

This is how you could change your code:

session = requests.Session()
session.auth = HTTPBasicAuth(uname, pswd)
res = session.get('http://localhost:9200')

And the get will use auth defined above it implicitly.

Check the page linked above, there are plenty examples.

And if you don't intend to reuse the connection, you can drop Session and go with auth in the get, like Narenda suggests in the other answer.

3 Comments

I'm getting a new error now: ConnectionError: HTTPConnectionPool(host='localhost', port=9200): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x0000023B52C0FE10>: Failed to establish a new connection: [WinError 10061] No connection could be made because the target machine actively refused it',)). How can I resolve this? Thanks
This means that you are probably making too many requests/connections. What does the elasticsearch log say?
C:\Users\kailash.sharma\Downloads\elasticsearch-6.2.2\elasticsearch-6.2.2\logs. There are no log files in this folder. Is there any other way to check the elasticsearch log? Thanks
0

Try this simple way to do this.

import requests
from requests.auth import HTTPBasicAuth
res = requests.get(url="url", auth=HTTPBasicAuth("username", "password"))
print(res.json())

I hope this helps.

2 Comments

I'm getting a new error now: ConnectionError: HTTPConnectionPool(host='localhost', port=9200): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x0000023B52C0FE10>: Failed to establish a new connection: [WinError 10061] No connection could be made because the target machine actively refused it',)). How can I resolve this? Thanks
@vadirajjahagirdar didn't work for me,, still got same error like upper comment..
0

First create a Basic header auth token based from your username and pass using base64 module, if you dont know how to use it just create Basic Authentication Header Here:

After doing so, create a dictionary which would be passed as the authentication header. See sample code below:

  import requests

  #username = elastic password = elastic
  auth_token = 'ZWxhc3RpYzplbGFzdGlj'
  head = head = {
  'Content-Type' : 'application/json; charset=utf8',
  'Authorization' : 'Basic %s' % auth_token,
  'User-Agent': 'Mozilla/5.0 (Windows NT 6.0; WOW64; rv:24.0) Gecko/20100101 
   Firefox/24.0'
  }

  res = requests.get('http://localhost:9200', header=head)
  print(res.json())

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.