<commit_before># API Star ✨🚀✨🌟

A smart Web API framework, designed for Python 3.

[![Build Status](https://travis-ci.org/tomchristie/apistar.svg?branch=master)](https://travis-ci.org/tomchristie/apistar)
[![codecov](https://codecov.io/gh/tomchristie/apistar/branch/master/graph/badge.svg)](https://codecov.io/gh/tomchristie/apistar)
[![Package version](https://badge.fury.io/py/apistar.svg)](https://pypi.python.org/pypi/apistar)
[![Python versions](https://img.shields.io/pypi/pyversions/apistar.svg)](https://www.python.org/doc/versions/)

**Community:** https://discuss.apistar.org/ 🤔 💭 🤓 💬 😎

![screenshot](docs/img/apistar.gif)

---

# Features

Why should you consider using API Star for your next Web API project?

* **API documentation** - Interactive API documentation, that's guaranteed to always
be in sync with your codebase.
* **Client libraries** - JavaScript and Python client libraries, driven by the schemas that API Star generates.
* **Schema generation** - Support for generating Swagger or RAML API schemas.
* **Expressive** - Type annotated views, that make for expressive, testable code.
* **Performance** - Dynamic behavior for determining how to run each view makes API Star incredibly efficient.

---

# Table of Contents

- [Quickstart](#quickstart)
- [HTTP](#http)
    - [Requests](#requests)
    - [Responses](#responses)
    - [URL Routing](#url-routing)
- [Schemas](#schemas)
    - [Data Validation](#data-validation)
    - [Serialization](#serialization)
    - [Generating API Schemas](#generating-api-schemas)
- [Building Websites](#building-websites)
    - [Templates](#templates)
    - [Static Files](#static-files)
- [Settings & Environment](#settings--environment)
    - [Application settings](#application-settings)
    - [Environment](#environment)
- [Backends](#backends)
  - [SQLAlchemy](#sqlalchemy)
  - [Django ORM](#django-orm)
- [Testing](#testing)
- [Components](#components)
- [WSGI](#wsgi)
- [Performance](#performance)
- [Deployment](#deployment)
    - [The Development Server](#the-development-server)
    - [Running in Production](#running-in-production)
    - ["Serverless" Deployments](#serverless-deployments)
- [Development](#development)

---

# Quickstart

Install API Star:

    $ pip3 install apistar

Create a new project:

    $ apistar new . --layout minimal
    app.py
    tests.py
    $ cat app.py
    from apistar import App, Include, Route
    from apistar.docs import docs_routes
    from apistar.statics import static_routes


    def welcome(name=None):
        if name is None:
            return {'message': 'Welcome to API Star!'}
        return {'message': 'Welcome to API Star, %s!' % name}


    routes = [
        Route('/', 'GET', welcome),
        Include('/docs', docs_routes),
        Include('/static', static_routes)
    ]

    app = App(routes=routes)


Run the application:

    $ apistar run
    Running at http://localhost:8080/

Run the tests:

    $ apistar test
    tests.py ..
    ===== 2 passed in 0.05 seconds =====

View the interactive API documentation:

    $ open http://localhost:8080/docs/

![screenshot](docs/img/apistar.png)

---

# HTTP

## Requests

API Star allows you to dynamically inject various information about the
incoming request into your views using type annotation.

```python
from apistar import http

def show_request(request: http.Request):
    return {
        'method': request.method,
        'url': request.url,
        'headers': dict(request.headers)
    }

def show_query_params(query_params: http.QueryParams):
    return {
        'params': dict(query_params)
    }

def show_user_agent(user_agent: http.Header):
    return {
        'user-agent': user_agent
    }
```

Some of the components you might use most often:

| Component     | Description |
| ------------- | ----------- |
| `Request`     | The HTTP request. Includes `.method`, `.url`, and `.headers` attributes. |
| `Headers`     | The request headers, returned as a dictionary-like object. |
| `Header`      | Lookup a single request header, corresponding to the argument name.<br/>Returns a string or `None`. |
| `QueryParams` | The request query parameters, returned as a dictionary-like object. |
| `QueryParam`  | Lookup a single query parameter, corresponding to the argument name.<br/>Returns a string or `None`. |
| `Body`        | The request body. Returns a bytestring. |

## Responses

By default API star expects view to return plain data, and will return
`200 OK` responses.

```python
def create_project():
    return {'name': 'new project', 'id': 123}
```

You can instead set the status code or headers by annotating the view as
returning a `Response`.

```python
def create_project() -> Response:
    data = {'name': 'new project', 'id': 123}
    headers = {'Location': 'http://example.com/project/123/'}
    return Response(data, status=201, headers=headers)
```

## URL Routing

Use `{curly_braces}` in your URL conf to include a URL path parameter.


```python
def echo_username(username):
    return {'message': f'Welcome, {username}!'}

app = App(routes=[
    Route('/{username}/', 'GET', echo_username)
])
```

Use type annotation on the view method to include typed URL path parameters.

```python
users = {0: 'penny', 1: 'benny', 2: 'jenny'}

def echo_username(user_id: int):
    username = users[user_id]
    return {'message': f'Welcome, {username}!'}

app = App(routes=[
    Route('/{user_id}/', 'GET', echo_username)
])
```

Parameters which do not correspond to a URL path parameter will be treated as
query parameters for `GET` and `DELETE` requests, or part of the request body
for `POST`, `PUT`, and `PATCH` requests.

```python
def echo_username(username):
    if username is None:
        return {'message': 'Welcome!'}
    return {'message': f'Welcome, {username}!'}

app = App(routes=[
    Route('/hello/', 'GET', echo_username)
])<commit_msg>Add include example to README (#185)<commit_after># API Star ✨🚀✨🌟

A smart Web API framework, designed for Python 3.

[![Build Status](https://travis-ci.org/tomchristie/apistar.svg?branch=master)](https://travis-ci.org/tomchristie/apistar)
[![codecov](https://codecov.io/gh/tomchristie/apistar/branch/master/graph/badge.svg)](https://codecov.io/gh/tomchristie/apistar)
[![Package version](https://badge.fury.io/py/apistar.svg)](https://pypi.python.org/pypi/apistar)
[![Python versions](https://img.shields.io/pypi/pyversions/apistar.svg)](https://www.python.org/doc/versions/)

**Community:** https://discuss.apistar.org/ 🤔 💭 🤓 💬 😎

![screenshot](docs/img/apistar.gif)

---

# Features

Why should you consider using API Star for your next Web API project?

* **API documentation** - Interactive API documentation, that's guaranteed to always
be in sync with your codebase.
* **Client libraries** - JavaScript and Python client libraries, driven by the schemas that API Star generates.
* **Schema generation** - Support for generating Swagger or RAML API schemas.
* **Expressive** - Type annotated views, that make for expressive, testable code.
* **Performance** - Dynamic behavior for determining how to run each view makes API Star incredibly efficient.

---

# Table of Contents

- [Quickstart](#quickstart)
- [HTTP](#http)
    - [Requests](#requests)
    - [Responses](#responses)
    - [URL Routing](#url-routing)
- [Schemas](#schemas)
    - [Data Validation](#data-validation)
    - [Serialization](#serialization)
    - [Generating API Schemas](#generating-api-schemas)
- [Building Websites](#building-websites)
    - [Templates](#templates)
    - [Static Files](#static-files)
- [Settings & Environment](#settings--environment)
    - [Application settings](#application-settings)
    - [Environment](#environment)
- [Backends](#backends)
  - [SQLAlchemy](#sqlalchemy)
  - [Django ORM](#django-orm)
- [Testing](#testing)
- [Components](#components)
- [WSGI](#wsgi)
- [Performance](#performance)
- [Deployment](#deployment)
    - [The Development Server](#the-development-server)
    - [Running in Production](#running-in-production)
    - ["Serverless" Deployments](#serverless-deployments)
- [Development](#development)

---

# Quickstart

Install API Star:

    $ pip3 install apistar

Create a new project:

    $ apistar new . --layout minimal
    app.py
    tests.py
    $ cat app.py
    from apistar import App, Include, Route
    from apistar.docs import docs_routes
    from apistar.statics import static_routes


    def welcome(name=None):
        if name is None:
            return {'message': 'Welcome to API Star!'}
        return {'message': 'Welcome to API Star, %s!' % name}


    routes = [
        Route('/', 'GET', welcome),
        Include('/docs', docs_routes),
        Include('/static', static_routes)
    ]

    app = App(routes=routes)


Run the application:

    $ apistar run
    Running at http://localhost:8080/

Run the tests:

    $ apistar test
    tests.py ..
    ===== 2 passed in 0.05 seconds =====

View the interactive API documentation:

    $ open http://localhost:8080/docs/

![screenshot](docs/img/apistar.png)

---

# HTTP

## Requests

API Star allows you to dynamically inject various information about the
incoming request into your views using type annotation.

```python
from apistar import http

def show_request(request: http.Request):
    return {
        'method': request.method,
        'url': request.url,
        'headers': dict(request.headers)
    }

def show_query_params(query_params: http.QueryParams):
    return {
        'params': dict(query_params)
    }

def show_user_agent(user_agent: http.Header):
    return {
        'user-agent': user_agent
    }
```

Some of the components you might use most often:

| Component     | Description |
| ------------- | ----------- |
| `Request`     | The HTTP request. Includes `.method`, `.url`, and `.headers` attributes. |
| `Headers`     | The request headers, returned as a dictionary-like object. |
| `Header`      | Lookup a single request header, corresponding to the argument name.<br/>Returns a string or `None`. |
| `QueryParams` | The request query parameters, returned as a dictionary-like object. |
| `QueryParam`  | Lookup a single query parameter, corresponding to the argument name.<br/>Returns a string or `None`. |
| `Body`        | The request body. Returns a bytestring. |

## Responses

By default API star expects view to return plain data, and will return
`200 OK` responses.

```python
def create_project():
    return {'name': 'new project', 'id': 123}
```

You can instead set the status code or headers by annotating the view as
returning a `Response`.

```python
def create_project() -> Response:
    data = {'name': 'new project', 'id': 123}
    headers = {'Location': 'http://example.com/project/123/'}
    return Response(data, status=201, headers=headers)
```

## URL Routing

Use `{curly_braces}` in your URL conf to include a URL path parameter.


```python
def echo_username(username):
    return {'message': f'Welcome, {username}!'}

app = App(routes=[
    Route('/{username}/', 'GET', echo_username)
])
```

Use `Include` to include a list of routes.

```python
star_routes=[
    Route('/', 'GET', list_stars),
    Route('/', 'POST', create_new_star),
    Route('/{star_id}', 'PUT', edit_star),
    Route('/{star_id}', 'DELETE', delete_star)
]

app = App(routes=[
    Include('/api/star', star_routes)
])
```

Use type annotation on the view method to include typed URL path parameters.

```python
users = {0: 'penny', 1: 'benny', 2: 'jenny'}

def echo_username(user_id: int):
    username = users[user_id]
    return {'message': f'Welcome, {username}!'}

app = App(routes=[
    Route('/{user_id}/', 'GET', echo_username)
])
```

Parameters which do not correspond to a URL path parameter will be treated as
query parameters for `GET` and `DELETE` requests, or part of the request body
for `POST`, `PUT`, and `PATCH` requests.

```python
def echo_username(username):
    if username is None:
        return {'message': 'Welcome!'}
    return {'message': f'Welcome, {username}!'}

app = App(routes=[
    Route('/hello/', 'GET', echo_username)
])
{'fraction_non_alphanumeric': 0.14960629921259844, 'fraction_numerical': 0.005553253211769581, 'mean_word_length': 3.684006211180124, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 18, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3151593', 'n_tokens_mistral': 3900, 'n_tokens_neox': 3632, 'n_words': 1109}