Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help with session variables #212

Closed
CRad14 opened this issue May 10, 2019 · 5 comments
Closed

Help with session variables #212

CRad14 opened this issue May 10, 2019 · 5 comments
Labels
question Question or problem question-migrate

Comments

@CRad14
Copy link

CRad14 commented May 10, 2019

I am pretty new to python and Rest APIs in general so I am hoping someone could help me out with what I hope is a simple question.

I am trying to figure out how to create a variable per logged in user that is used throughout the app. Current the closest thing I have is creating a global variable

app = FastAPI()

security = HTTPBasic()

@app.get("/login")
def login(request: Request, credentials: HTTPBasicCredentials = Depends(security)):
    global instance
    instance= Instance(credentials.username, credentials.password)

@app.get("/iitem")
def get(item):
    return {"SecretStuff": instance.subprop.classifiedinfo}

For extra context the variable I am creating is an instantiated class which is a connection to an application server. For the logged in user I then want to be able to use that connection to the throughout the app.

I saw the tutorial on the sql database, but I know that is creating something per request, whereas mine is per session....Plus I am not sure how I would convert it to my use in the first place.

My current method of using global variables obviously doesn't work out too well either as then anyone would be able to use requests that utilize that variable.

Any help would be greatly appreciated!!!!!!!!!!

@CRad14 CRad14 added the question Question or problem label May 10, 2019
@tiangolo
Copy link
Owner

Hey @CRad14, I'm glad to see you chose to learn FastAPI!

Summary

In an API (or almost in any web application, written in any language or framework), you normally separate the logic of what happens in the sequence of getting a request (sent by the client, let's say a browser with a frontend) and generating the response for that request (that's what your FastAPI app will return to the user).

When your client (e.g. user in a browser) interacts with your API, it sends a single request asking for something.

In that request, this user sends attached something that identifies him with the app. Your app (FastAPI) verifies the attached "thing" (some credentials) to verify "who is requesting this", from it, it gets the user that sent the request. Let's say, it extracts the email from those credentials. And then using that email, the app gets the user data from the database.

Then it uses that user data from the database to generate the response (let's say, to find the items for that user). And then sends the response back.

At this point, when that single request/response cycle is done, the app forgets about that specific user.

For the next request, the client attaches again that "thing" that authenticates him with the app, and the process starts again.

Multiple users

Your FastAPI app will do this process for each request-response, for each path operation (for each URL), and will do it handling thousands of users at the same time, during the same second (potentially).

So, you cannot save one user in a global variable, when you are handling lots of users at the same time, each user would override the previous one.

So, you need the client to send those credentials in each request.

Credentials

The thing attached to each request (the "credentials") in modern APIs is an HTTP header Authorization with a value that contains a "token" (a string with some data encoded).

So, your client can request data to a specific URL, and possibly send data in the body (let's say, a JSON body), and add the credentials in a header, without affecting the body payload or the URL.

Some applications also use Cookies. Cookies also go in HTTP headers, but are handled more or less automatically by the browser, and might not work as well as headers.

State and logic

Note: if this section seems too complex or abstract, don't worry about it, just skip it.

Building any type of apps (including a web API), it's a common practice to put the logic in one place and the "state" of the system or data in another.

The logic is all the computation that is done, all your Python code.

The "state" is your app's data. It contains your users, items or anything that you save there, that changes over time and is stored. That data is, more or less, the actual content of your system.

It might be the case that your app only performs actions, without state/data, but if you have independent users, that's already state/data.

But that content alone doesn't do much. You need all that logic (the Python code) to interact with that content, to read it, modify it, process it, etc.

As that state/data/content is what changes over time, and it contains the value of your system, you want to keep it safe. If you change something (let's say, you create a new item for a user), you want that change to stay there, even if you restart the computer. So, you normally store state in a database of some type. It could even be just a text file, but it would be stored somewhere else not inside your code (as your code doesn't change by itself).

And your code, the logic, is not changing and evolving by itself (only when you change it). And that same code works with whatever is the current state/data. The results change according to that data.

So, you would normally save the users, items, etc in a database, and your API would check that database every time a user logs in, tries to do something in the system, etc. But your app code wouldn't have information about who is logged in and who isn't internally in its code/variables. The user data is in the database, in the client (the user), etc. Your app takes data from your users and from the database, processes it, and then returns data to your users and puts data in the database. But it doesn't store itself that data internally.

@ankush981
Copy link

Hey, @tiangolo! I'm a PHP developer who stumbled upon FastAPI and quite like it. 😄 I do have a similar question: is FastAPI API-only or is it possible to build a traditional web app? I've searched through the docs many times and I don't see how sessions are done in FastAPI. I'm sure for very experienced developers it's "trivial", but I'm more used to just using the things baked in. Anyway, some help on this will be much appreciated!

@dmontagu
Copy link
Collaborator

dmontagu commented Jul 10, 2019

@ankush981 it is definitely possible to build a traditional web app with FastAPI!

One way to manage a session is with Cookies (described here: https://fastapi.tiangolo.com/tutorial/cookie-params/), though you’d need to build the infrastructure for tracking it in the database/etc.

The FastAPI project generator creates a basic Vue-based web app (here: https://github.com/tiangolo/full-stack-fastapi-postgresql).

@tiangolo
Copy link
Owner

Thanks for the help @dmontagu!

I think the original issue was solved, right @ankush981 ? May we close this issue?

@github-actions
Copy link
Contributor

Assuming the original issue was solved, it will be automatically closed now. But feel free to add more comments or create new issues.

@tiangolo tiangolo changed the title [QUESTION] Help with session variables Help with session variables Feb 24, 2023
@tiangolo tiangolo reopened this Feb 28, 2023
Repository owner locked and limited conversation to collaborators Feb 28, 2023
@tiangolo tiangolo converted this issue into discussion #8293 Feb 28, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
question Question or problem question-migrate
Projects
None yet
Development

No branches or pull requests

4 participants