# OreoWeb

## Why Oreoweb

Oreoweb is a **Python web framework**. It is built on top of asyncio and implements the WSGI standard.

With Oreoweb, you can use **asynchronous programming** available in Python 3.6+ to build fast, scalable and real-time capable web APIs for AI development.

Oreoweb in steve jobs style  " A web framework + Database + AI library". Oreoweb allows developers to build web apps powered by AI within a single python script without requirements of integrating 3rd party libraries.

## Installation

```
$ pip install oreoweb
```

{% hint style="info" %}
&#x20;

* You will need **Python 3.6 and above** to use Oreoweb. You can get Python from [python.org](https://www.python.org/downloads/) or via the package manager of your OS.
* On Linux, due to a known limitation in httptools, you also need to install `python-dev` for your current version of Python, e.g. `apt-get install python3.7-dev` for Python 3.7.
  {% endhint %}

### Oreoweb CLI <a href="#bocadillo-cli" id="bocadillo-cli"></a>

&#x20;You may also want to install Oreoweb CLI. It comes with useful command line tools to help with project generation and other common tasks.

```bash
pip install oreoweb-cli
```

## Features of Oreoweb

## Static Files

Place files in the `static` folder at the root location, and they will be available at the corresponding URL

Statics files location:

By default, static assets are served at the `/static/` URL root and are searched for in a `static/` directory relative to where the app is executed.

&#x20;You can modify the static files directory using  the  following

```
app = Oreoweb(static_dir="static_dir_name")
```

### Templates <a href="#static-files-location" id="static-files-location"></a>

The default folder for templates is `templates`. You can change it when initializing the main Oreoweb class:

```
app = Oreoweb(templates_dir="templates_dir_name")
```

Templates Examples

```
@app.route("/show/template")
def handler_with_template(req, resp):
    resp.html = app.template("example.html", context={"title": "Awesome Framework", "body": "welcome to the future!"})
```

\
Custom Exception Handler
------------------------

Sometimes, depending on the exception raised, you may want to do a certain action. For such cases, you can register an exception handler:

```
def on_exception(req, resp, exception):
    if isinstance(exception, HTTPError):
        if exception.status == 404:
            resp.text = "Unfortunately the thing you were looking for was not found"
        else:
            resp.text = str(exception)
    else:
        # unexpected exceptions
        if app.debug:
            debug_exception_handler(req, resp, exception)
        else:
            print("These unexpected exceptions should be logged.")

app = Oreoweb(debug=False)
app.add_exception_handler(on_exception)
```

## Custom Middleware

&#x20;You can create custom middleware classes by inheriting from the oreoweb.middleware.Middleware class and override its two methods that are called before and after each request:

```
from oreoweb import oreoweb
from oreoweb.middleware import Middleware

app = Oreoweb()


class SimpleCustomMiddleware(Middleware):
    def process_request(self, req):
        print("Before dispatch", req.url)

    def process_response(self, req, res):
        print("After dispatch", req.url)


app.add_middleware(SimpleCustomMiddleware)

```

## Inbuilt Deep learning integration

**Intuitive APIs**

```
# define a model
net = Net([Dense(50), ReLU(), Dense(100), ReLU(), Dense(10)]) 
model = Model(net=net, loss=MSE(), optimizer=Adam(lr))

# train
for batch in iterator(train_x, train_y):
    preds = model.forward(batch.inputs)
    loss, grads = model.backward(preds, batch.targets)
    model.apply_grads(grads)
```

**Components**

* layers: Dense, Conv2D, ConvTranspose2D, RNN, MaxPool2D, Dropout, BatchNormalization
* activation: ReLU, LeakyReLU, Sigmoid, Tanh, Softplus
* losses: SoftmaxCrossEntropy, SigmoidCrossEntropy, MAE, MSE, Huber
* optimizer: RAdam, Adam, SGD, Momentum, RMSProp, Adagrad, Adadelta

## Inbuilt NoSql Database integration

```
from oreoweb import oreodb
mydb = OreoDB("./mydb.db")
mydb.set("name" , "Harish") #Sets Value
mydb.get("name")
```

## Automl Integration(Coming Soon)

```
from oreoweb import train
from oreoweb import predict

automl_train('train_titanic.csv', '/tmp/test/model.pkl','classification)
automl_predict('train_titanic.csv','test_titanic.csv','/tmp/test/model.pkl')
```

## Templating Engine

There are two types of tags, `blocks` and `variables`.

#### Variables

```
<div>{{my_var}}</div>
```

#### Blocks

There are three types of blocks – `if`, `each` and `call`.

**Loops**

```
{% each items %}
    <div>{{it}}</div>
{% end %}

{% each [1,2,3] %}
    <div>{{it}}</div>
{% end %}
```

`it` references the current item in the iteration and it is scoped to this item's attributes. To access attributes of the parent context use `..`. For example:

```
{% each items %}
    <div>{{..name}}</div><div>{{it}}</div>
{% end %}
```

**Conditionals**

Supported operators are: `>, >=, <, <=, ==, !=`. You can also use conditionals with things that evaluate to truth.

```
{% if num > 5 %}
    <div>more</div>
{% else %}
    <div>less or equal</div>
{% end %}

{% if items %}
    <div>we have items</div>
{% end %}
```

**Callables**

Callables can get passed positional or keyword arguments.

```
<div class='date'>{% call prettify date_created %}</div>
<div>{% call log 'here' verbosity='debug' %}</div>
```
