Metadata-Version: 2.4
Name: anzar
Version: 0.4.2
Summary: Anzar is a lightweight authentication and authorization framework that runs as a separate microservice
Keywords: Software Development,Authentication,Authorization,MicroService
Author: Hakou Guelfen
Author-email: Hakou Guelfen <hakoudev@gmail.com>
License-Expression: GPL-3.0
Classifier: Programming Language :: Python :: 3
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Topic :: Software Development
Requires-Dist: pydantic[email]>=2.11.7
Requires-Dist: python-dateutil>=2.9.0.post0
Requires-Dist: pyyaml>=6.0.2
Requires-Dist: requests>=2.32.5
Requires-Dist: flask>=3.1.3 ; extra == 'flask'
Requires-Dist: pyjwt>=2.12.1 ; extra == 'flask'
Requires-Dist: redis>=7.3.0 ; extra == 'redis'
Requires-Python: >=3.11
Project-URL: Bug, https://gitlab.com/anzar_software/python-sdk/-/work_items
Project-URL: Documentation, https://anzar_software.gitlab.io/docs
Project-URL: Homepage, https://gitlab.com/anzar_software/python-sdk
Provides-Extra: flask
Provides-Extra: redis
Description-Content-Type: text/markdown

# Anzar SDK Documentation

## Server

```python
from anzar_openapi import Role
from flask import g
from flask import Flask, jsonify
from anzar.server.flask import require_auth, requires_role

app = Flask(__name__)
CORS(app, origins=["http://localhost:5173"])


@app.route("/protected")
@require_auth(secret, audience="web-app")
def me():
    return jsonify(g.user_id)


@app.route("/admin")
@requires_role(secret, role=Role.USER, audience="web-app")
def admin():
    return jsonify(f"admin panel, {g.user_id}")


if __name__ == "__main__":
    app.run(debug=True)
```

---


## Client

## Install The Python SDK
In a python project run the following command to install the anzar package.

**uv**
```bash
$ uv add anzar
```

**pip**
```bash
# in a virtual env run
$ pip install anzar
```

## Create Anzar Auth Instance
in your main entry file (`main.py` for example),
import `anzar.yml` and parse it as a YAML file
```python
def load_config(path: str) -> AnzarConfig:
    import yaml

    try:
        with open(path, "r") as f:
            data = yaml.safe_load(f)
        return AnzarConfig(**data)
    except Exception as e:
        import sys

        sys.exit("check your configuration file: anzar.yml")
```

import Anzar Auth and create your auth instance
```python 
# Initialize once at application startup
# The SDK will communicate with your Anzar container at the configured api_url
from anzar import Anzar

config = load_config("anzar.yml")
anzar = Anzar(config, options=None)
```


**Note** "Configuring Token Persistence"
    To keep users logged in across restarts, choose a token storage adapter.

    ```python
    from anzar.adapters import RedisStorage
    from anzar.types import SdkOptions 

    anzar = Anzar(config, SdkOptions(storage=RedisStorage()))
    ```

## Basic Usage
Anzar provides authentication support for email and password.

📝 **Note:** Other methods of authentication will be implemented later

### Sign Up
To sign up a user you need to call the method register with the user's information.
```python
from anzar.types import ApiException, AuthResponse, ErrorCode

try:
    data: AuthResponse = anzar.Auth.register({
      "username": "username",
      "email": "user@example.com",
      "password": "password"
    })
except ApiException as e:
    if e.data is None:
        return

    if e.data.code == ErrorCode.InvalidCredentials:
        show_error("Invalid email or password.")
    elif e.data.code == ErrorCode.AccountNotVerified:
        show_error("Please verify your email before logging in.")
```

📝 **Note:** By default, the users are automatically signed in after they successfully sign up.
             Disabling this behavior will be implemented later

### Sign In
To sign in a user you need to call the method login.
```python
from anzar.types import ApiException, AuthResponse, ErrorCode

try:
    data: AuthResponse = anzar.Auth.login({
      "email": "user@example.com",
      "password": "password"
    })
except ApiException as e:
    if e.data is None:
        return

    if e.data.code == ErrorCode.InvalidCredentials:
        show_error("Invalid email or password.")
    elif e.data.code == ErrorCode.AccountNotVerified:
        show_error("Please verify your email before logging in.")

