# 09 - Account Actions

## User Delete

The user delete view will delete the user from the database using the `user` model's delete method. Add the following (and the rest of the snippets below), to your `views/user_view.py` file

```python
@user_api.route('/me', methods=['DELETE'])
@Auth.auth_required  # <- the decorator we created before
def delete():
    user = UserModel.get_one_user(g.user.get('id'))
    user.delete()
    return custom_response({'message': 'deleted'}, 204)
```

### Get all Users

This method does what it says. It will return a list of all users.

```python
@user_api.route('/', methods=['GET'])
@Auth.auth_required
def get_all():
    users = UserModel.get_all_users()
    ser_users = user_schema.dump(users, many=True).data
    return custom_response(ser_users, 200)
```

### Get One User

Just like the view before, this endpoint will retrieve a single user *by ID*.

```python
@user_api.route('/<int:user_id>', methods=['GET'])
@Auth.auth_required
def get_user(user_id):
    '''
    Get a single user
    '''
    user = UserModel.get_one_user(user_id)
    if not user:
        return custom_response({'error': 'user not found'}, 404)

    ser_user = user_schema.dump(user).data
    return custom_response(ser_user, 200)
```

### Get Me

This endpoint utilizes the applications context proxy, `g`. `g` is a namespace object that stores all or every bit of information needed during the applications life cycle. In other words, Whenever someone uses the app, data needed for the app to run, is stored in `g`.

```python
@user_api.route('/me', methods=['GET'])
@Auth.auth_required
def get_me():
    '''
    Get owners user information (me)
    '''

    user = UserModel.get_one_user(g.user.get('id'))
    ser_user = user_schema.dump(user).data
    return custom_response(ser_user, 200)
```

### Login

This endpoint logs in a user. It does this by verifying the password hash to the hashed password stored in the database, along with the email. Then, it will return a token for the user to use for any requests they would like to make

```python
@user_api.route('/login', methods=['POST'])
def login():
    '''
    Validates and returns a web token
    if the user credentials are verified
    '''
    req_data = request.get_json()

    data, error = user_schema.load(req_data, partial=True)

    if error:
        return custom_response(error, 400)

    if not data.get('email') or not data.get('password'):
        return custom_response({'error': 'email and password required to login'})

    user = UserModel.get_user_by_email(data.get('email'))

    if not user:
        return custom_response({'error': 'invalid credentials'}, 400)

    if not user.check_hash(data.get('password')):
        return custom_response({'error': 'invalid credentials'})

    ser_data = user_schema.dump(user).data

    token = Auth.generate_token(ser_data.get('id'))

    return custom_response({'token': token}, 200)
```

### Update User

This endpoint will take in new information and modify it to the new body, returning a `bad request` status code if the body is missing important bit of information. Then it will persist the changes, and send back a `200` and the new users information

```python
@user_api.route('/me', methods=['PUT'])
@Auth.auth_required
def update():
    '''
    Allows owner of profile (me)
    to update the user information
    '''

    req_data = request.get_json()
    data, error = user_schema.load(req_data, partial=True)
    if error:
        return custom_response(error, 400)

    user = UserModel.get_one_user(g.user.get('id'))
    user.update(data)
    ser_user = user_schema.dump(user).data
    return custom_response(ser_user, 200)
```

### Registering the User Blueprint

The final step before the user views are finished up, is we need to register the blueprint. This is the `user_api` object in `user_views.py`. We do this by adding the following code to our `src/app.py`

```
    app.register_blueprint(user_blueprint, url_prefix='/api/v1/users')
```

This line should be inside the `create_app` function, just after the `app.config` calls, and before we use `bcrypt`. We do this because we have created the app, but we haven't added the extra goodies we just created to our app. This is called *\*\****Registering a Blueprint**. A snippet of the `create_app` function is shown below

```python
def create_app(env_name='development'):
    '''Create app context'''

    app = Flask(__name__)

    app.config.from_object(app_config[env_name])
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

    # Add this line
    app.register_blueprint(user_blueprint, url_prefix='/api/v1/users')

    bcrypt.init_app(app)
    db.init_app(app)

    return app
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://eleven-fifty-academy.gitbook.io/python-301-flask/09-account-actions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
