diezo / Ensta

🔥 Fast & Reliable Python Package For Instagram API - 2024
https://bit.ly/ensta-discord
MIT License
371 stars 44 forks source link

Using Ensta with flask app #42

Closed OlguD closed 11 months ago

OlguD commented 11 months ago

When I run this flask app on my local machine it doesn't give any error, it runs perfectly but when I run flask app on vds server, it gives an error.

 * Serving Flask app 'app'
 * Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://xxxxxxxxxxxxx:8080
Press CTRL+C to quit
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 122-356-326
194.146.159.67 - - [01/Dec/2023 21:57:37] "POST /login HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/root/api/API/venv/lib/python3.11/site-packages/ensta/Host.py", line 61, in load_session
    super().__init__(session_data, self.proxy)
  File "/root/api/API/venv/lib/python3.11/site-packages/ensta/SessionHost.py", line 72, in __init__
    if not skip_auth_verification and not self.authenticated():
                                          ^^^^^^^^^^^^^^^^^^^^^
  File "/root/api/API/venv/lib/python3.11/site-packages/ensta/SessionHost.py", line 105, in authenticated
    http_response = self.request_session.get(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/api/API/venv/lib/python3.11/site-packages/requests/sessions.py", line 602, in get
    return self.request("GET", url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/api/API/venv/lib/python3.11/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/api/API/venv/lib/python3.11/site-packages/requests/sessions.py", line 725, in send
    history = [resp for resp in gen]
              ^^^^^^^^^^^^^^^^^^^^^^
  File "/root/api/API/venv/lib/python3.11/site-packages/requests/sessions.py", line 725, in <listcomp>
    history = [resp for resp in gen]
              ^^^^^^^^^^^^^^^^^^^^^^
  File "/root/api/API/venv/lib/python3.11/site-packages/requests/sessions.py", line 191, in resolve_redirects
    raise TooManyRedirects(
requests.exceptions.TooManyRedirects: Exceeded 30 redirects.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/root/api/API/venv/lib/python3.11/site-packages/flask/app.py", line 1478, in __call__
    return self.wsgi_app(environ, start_response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/api/API/venv/lib/python3.11/site-packages/flask/app.py", line 1458, in wsgi_app
    response = self.handle_exception(e)
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/api/API/venv/lib/python3.11/site-packages/flask/app.py", line 1455, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/api/API/venv/lib/python3.11/site-packages/flask/app.py", line 869, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/api/API/venv/lib/python3.11/site-packages/flask/app.py", line 867, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/api/API/venv/lib/python3.11/site-packages/flask/app.py", line 852, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/api/API/app.py", line 29, in login
    session['host'] = Host(username, password)
                      ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/api/API/venv/lib/python3.11/site-packages/ensta/Host.py", line 33, in __init__
    self.load_session()
  File "/root/api/API/venv/lib/python3.11/site-packages/ensta/Host.py", line 62, in load_session
    except Exception: return self.new_session()
                             ^^^^^^^^^^^^^^^^^^
  File "/root/api/API/venv/lib/python3.11/site-packages/ensta/Host.py", line 65, in new_session
    session_data: str = new_session_id(self.username, self.password, self.proxy)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/api/API/venv/lib/python3.11/site-packages/ensta/Authentication.py", line 69, in new_session_id
    if response_json.get("status", "") != "ok": raise AuthenticationError("User doesn't exist.")
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ensta.lib.Exceptions.AuthenticationError: User doesn't exist.

I use the same post requests code for testing the flask API:

import requests

# Base URL for the Flask application
#base_url = 'http://127.0.0.1:8090'
base_url = 'http://SERVER_URL:8080'

# Sample user credentials
username = 'instagram_username'
password = 'instagram_password'

# Create a session
session = requests.Session()

# Login Request
login_data = {'username': username, 'password': password}
login_response = session.post(f'{base_url}/login', data=login_data)
print(login_response.json())  # Expected output: {'status': 'Login successful'}

# Check if login was successful before proceeding with the image upload
if login_response.json().get('status') == 'Login successful':
    # Send POST request to /fetchProfileInfo endpoint
    upload_response = session.post(f'{base_url}/fetchProfileInfo', data={'username': username})
    print(upload_response.json())

My flask app's login endpoint is this.

# Flask-Session configuration
app.config['SESSION_TYPE'] = 'filesystem'
# app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(minutes=30)
app.config['SESSION_PERMANENT'] = True  # Set the session to be permanent
Session(app)

@app.route('/login', methods=['POST'])
def login():
    # Check if the user is already logged in
    if 'host' in session:
        return jsonify({'status': 'User is already logged in'})

    # Get user login information
    username = request.form.get('username')
    password = request.form.get('password')

    # User login
    session.permanent = True
    session['host'] = Host(username, password)
    session['_id'] = f'user_{username}'
    return jsonify({'status': 'Login successful'})

This is the endpoint that provides profile information after the user logged in

@app.route('/fetchProfileInfo', methods=['POST'])
def fetchProfileInfo():
    host = session.get('host')

    if not host:
        return jsonify({'status': 'User not logged in'})

    username = request.form.get('username')
    profile = host.profile(username)
    return jsonify({'response': profile})
OlguD commented 11 months ago

Does the only problem is using session in my flask app ? Can it cause this error ?

diezo commented 11 months ago

this is not the right way to exchange login sessions in ensta.

after logging in, ensta stores session data in a file named "ensta-session.txt". you should copy the json data in that file and return to the user. when the user wants to perform authenticated requests, he should provide the session data which your flask server will use in the host class by first storing that data in "ensta-session.txt" file and then initialising the host class so that it can fetch the session data from that file.

diezo commented 11 months ago

the reason why it works on your local machine could be because it already has the "ensta-session.txt" file while on your server, persistent storage may not be available for ensta to create session files.

you can rather use the "save & load" parameters while initialising the host class which will return the session data to your custom functions.

from ensta import Host

def savedata(data):
    # here's your session data. return it to the user and ask them to to pass this data everytime they perform an authenticated request
    ...

def loaddata():
    # here, you need to fetch that session data from cookies, headers or anything you're using and return in this function so that ensta can use it

    ...

    return data

host = Host(username, password, save=savedata, load=loaddata)
diezo commented 11 months ago

can you send me your flask server's code if possible? it'll help detect what the exact cause of error is and also debug the code as needed.

OlguD commented 11 months ago

Here is my flask app file

app.py.zip

I think the real problem is on the ensta-session.txt file. It is automaticaly created in server. But it doesn't initialising the host class, I guess this causes the error. By the way thank you for your quick response :).

this is not the right way to exchange login sessions in ensta.

after logging in, ensta stores session data in a file named "ensta-session.txt". you should copy the json data in that file and return to the user. when the user wants to perform authenticated requests, he should provide the session data which your flask server will use in the host class by first storing that data in "ensta-session.txt" file and then initialising the host class so that it can fetch the session data from that file.

diezo commented 11 months ago

i'll run the flask server on my machine and check if there's any error.

in the meantime, please do give this repository a star so that other developers can know about ensta as well.

thank you

OlguD commented 11 months ago

i'll run the flask server on my machine and check if there's any error.

in the meantime, please do give this repository a star so that other developers can know about ensta as well.

thank you

Appreciated

diezo commented 11 months ago

i don't know much about flask sessions, but here's what i would advice you to do:

  1. create a login endpoint where users give their username and password. in return of these, the server tries to log in and returns the session data back to the user.
  2. now, every time user wants to perform an authenticated request, he/she passes that session data string in each request through any medium (say cookies, headers etc).
  3. this session data then can easily be used to log into that user's session and perform authenticated requests.

here's the code for a more clearer reference: login endpoint:

def login(username, password):
    """
    this function takes "username" & "password", and returns session_data which is used to perform authenticated requests
    """

    try:
        host = Host(username, password)

        # login successful
        return {"status": "ok", "session_data": host.session_data}

    except Exception as e:
        # login failed
        return {"status": "fail", "message": str(e)}

endpoint to perform authenticated requests:

from ensta import SessionHost
import json

def profile_data(their_username):

    host = SessionHost(cookies["session_data"])  # yes, we'll use 'SessionHost' instead of 'Host'.

    profile = host.profile(their_username)

    return {"status": "ok", "profile": json.dumps(profile.__dict__)}

don't forget to update ensta because i've made some changes: pip install ensta --upgrade

OlguD commented 11 months ago

So when I do it this way, is there a possibility that the user will be banned? Can the user be caught in the fraud system?

diezo commented 11 months ago

if you talk specifically about this way of logging in, there's a low chance of your account being caught as ensta stores some other data as well along with the session_id in the session data string.

but that doesn't mean you can't get flagged. you can get flagged because of some other mistakes too (and no third-party api can guarantee this). you should be aware of some precautions including:

conclusion: if you use the method of logging in that i provided, you don't have to worry that much. but do take the precautions when using any third-party library.

hope it helps.

OlguD commented 11 months ago

I understand, thank you for your time. 😊

OlguD commented 11 months ago

i don't know much about flask sessions, but here's what i would advice you to do:

  1. create a login endpoint where users give their username and password. in return of these, the server tries to log in and returns the session data back to the user.
  2. now, every time user wants to perform an authenticated request, he/she passes that session data string in each request through any medium (say cookies, headers etc).
  3. this session data then can easily be used to log into that user's session and perform authenticated requests.

here's the code for a more clearer reference: login endpoint:

def login(username, password):
    """
    this function takes "username" & "password", and returns session_data which is used to perform authenticated requests
    """

    try:
        host = Host(username, password)

        # login successful
        return {"status": "ok", "session_data": host.session_data}

    except Exception as e:
        # login failed
        return {"status": "fail", "message": str(e)}

endpoint to perform authenticated requests:

from ensta import SessionHost
import json

def profile_data(their_username):

    host = SessionHost(cookies["session_data"])  # yes, we'll use 'SessionHost' instead of 'Host'.

    profile = host.profile(their_username)

    return {"status": "ok", "profile": json.dumps(profile.__dict__)}

don't forget to update ensta because i've made some changes: pip install ensta --upgrade