Skip to content

Commit

Permalink
1.7.3
Browse files Browse the repository at this point in the history
  • Loading branch information
Goldziher committed Aug 2, 2022
1 parent b3ca34d commit 40cc308
Show file tree
Hide file tree
Showing 24 changed files with 552 additions and 500 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repos:
exclude: "\\.idea/(.)*"
- id: trailing-whitespace
- repo: https://github.com/asottile/pyupgrade
rev: v2.37.2
rev: v2.37.3
hooks:
- id: pyupgrade
args: ["--py37-plus"]
Expand Down Expand Up @@ -42,7 +42,7 @@ repos:
exclude: "test_*"
args: ["-iii", "-ll", "-s=B308,B703"]
- repo: https://github.com/hadialqattan/pycln
rev: v2.0.4 # Possible releases: https://github.com/hadialqattan/pycln/releases
rev: v2.1.1 # Possible releases: https://github.com/hadialqattan/pycln/releases
hooks:
- id: pycln
args: [--config=pyproject.toml]
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,3 +287,7 @@

- Allow `Partial` to annotate fields of nested classes @Harry-Lees
- Add `OpenAPIConfig.use_handler_docstring` param

[1.7.3]

- Fix to routes being allowed under static paths and improvements to path resolution @Dr-Emann
88 changes: 49 additions & 39 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,65 +3,75 @@
To contribute code changes or update the documentation, please follow these steps:

1. Fork the upstream repository and clone the fork locally.
2. Install [poetry](https://python-poetry.org/), and install the project's dependencies with `poetry install --extras testing`
3. Install [pre-commit](https://pre-commit.com/) and install the hook by running `pre-commit install`
2. Install [poetry](https://python-poetry.org/), and install the project's dependencies
with `poetry install --extras testing`.
3. Install [pre-commit](https://pre-commit.com/) and install the hooks by running `pre-commit install` in the
repository's hook.
4. Make whatever changes and additions you wish and commit these - please try to keep your commit history clean.
5. Create a pull request to the main repository with an explanation of your changes
5. Create a pull request to the main repository with an explanation of your changes. The PR should detail the
contribution and link to any related issues - if existing.

Note: if you add new code or modify existing code - 100% test coverage is mandatory and tests should be well written.
## Code Contribution Guidelines

---
1. if you are adding or modifying existing code, please make sure to test everything you are doing. 100% test coverage
is mandatory and tests should be well
written.
2. All public functions and methods should be documented with a doc string. The project uses
the [google style docstring](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html).
Private methods should have a doc string explaining what they do, but do not require an elaborate doc string.

## Tox for testing against different versions
## Project Documentation

### Config
The documentation is located under the `/doc` folder, with the `mkdocs.yml` file in the project root.

1. Install and configure [pyenv](https://github.com/pyenv/pyenv)
2. Install required python versions via pyenv, e.g., `$ pyenv install 3.x.x` for each required version.
3. In root directory of library, create .python-version file in root, e.g.:

```text
3.10.5
3.9.13
3.8.13
3.7.13
```

4. Restart shell or run command like: `$ pyenv shell 3.10.5 3.9.13 3.8.13 3.7.13`
5. Remove any existing poetry environment: `$ poetry env remove python`
6. Tell poetry to use system python <sup>1</sup>: `$ poetry env use system`
7. `$ poetry install`
### Docs Theme and Appearance

1: Not sure if this is the "right" way to handle this yet, however this prevents poetry from reusing
the local environment in each of the tox environments.
We welcome contributions that enhance / improve the appearance and usability of the docs, as well as any images, icons
etc.

### Run
We use the excellent [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/) theme, which comes with a lot
of options out of the box. If you wish to contribute to the docs style / setup, or static site generation, you should
consult the theme docs as a first step.

`$ poetry run tox`
### Running the Docs Locally

#### force recreate tox environments
To run the docs locally, use docker and follow these steps:

`$ poetry run tox -r`
- pull the theme image with `docker pull squidfunk/mkdocs-material`
- run the docs site locally with `docker run --rm -it -p 8000:8000 -v ${PWD}:/docs squidfunk/mkdocs-material`

#### run specific tox environment
### Writing and Editing Docs

`$ poetry run tox -e py37`
We welcome contributions that enhance / improve the content of the docs. Feel free to add examples, clarify text,
restructure the docs etc. But make sure to follow these emphases:

#### run pre-commit only
- the docs should be as simple and easy to grasp as possible.
- the docs should be written in good idiomatic english.
- examples should be simple and clear.
- provide links where applicable.
- provide diagrams where applicable and possible.

`$ poetry run tox -e lint`
## Testing multiple python versions

---
Since the library needs to be compatible with older versions of python as well, it can be useful to run tests locally
against different python versions. To achieve this you can use the `tox` config that is included by doing the following.

## Contributing to the documentation

From the squidfunk/mkdocs-material [docker quick start guide](https://hub.docker.com/r/squidfunk/mkdocs-material):
1. Install [pyenv](https://github.com/pyenv/pyenv).
2. Install required python versions via pyenv, e.g., `$ pyenv install 3.x.x` for each required version.
3. In root directory of library, create .python-version file in root.
4. Restart shell.
5. Remove any existing poetry environment: `$ poetry env remove python`
6. Tell poetry to use system python <sup>1</sup>: `$ poetry env use system`
7. `$ poetry install`

`docker run --rm -it -p 8000:8000 -v ${PWD}:/docs squidfunk/mkdocs-material`
### Tox Commands

---
- Run: `$ poetry run tox`
- Force recreate tox environments: `$ poetry run tox -r`
- Run specific tox environment: `$ poetry run tox -e py37`
- Run pre-commit only: `$ poetry run tox -e lint`

## Release workflow
## Release workflow (Maintainers only)

1. Update changelog.md
2. Increment the version in pyproject.toml.
Expand Down
4 changes: 2 additions & 2 deletions docs/usage/0-the-starlite-app/0-the-starlite-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ The Starlite constructor accepts the following additional kwargs:
- `cors_config`: An instance of `starlite.config.CORSConfig`. If set this enables the [CORSMiddleware](../7-middleware.md#built-in-middlewares).
- `debug`: A boolean flag toggling debug mode on and off, if True, 404 errors will be rendered as HTML with a stack trace. This option should _not_ be used in production. Defaults to `False`.
- `dependencies`: A dictionary mapping dependency providers. See [dependency-injection](../6-dependency-injection.md).
- `exception_handlers`: A dictionary mapping exceptions or exception codes to handler functions. See [exception-handlers](../../17-exceptions#exception-handling).
- `exception_handlers`: A dictionary mapping exceptions or exception codes to handler functions. See [exception-handlers](../17-exceptions#exception-handling).
- `guards`: A list of guard callable. See [guards](../9-guards.md).
- `middleware`: A list of middlewares. See [middleware](../7-middleware.md).
- `on_shutdown`: A list of callables that are called during the application shutdown. See [startup-and-shutdown](./1-startup-and-shutdown.md).
- `on_startup`: A list of callables that are called during the application startup. See [startup-and-shutdown](./1-startup-and-shutdown.md).
- `openapi_config`: An instance of `starlite.config.OpenAPIConfig`. Defaults to the baseline config. See [open-api](../12-openapi.md).
- `parameters`: A mapping of parameters definition that will be available in all application paths. See [layered parameters](../3-parameters.md#layered-parameters).
- `parameters`: A mapping of parameters definition that will be available in all application paths. See [layered parameters](../3-parameters/4-layered-parameters.md).
- `response_class`: A custom response class to be used as the app's default. See [using-custom-responses](../5-responses.md#using-custom-responses).
- `response_headers`: A dictionary of `ResponseHeader` instances. See [response-headers](../5-responses.md#response-headers).
- `static_files_config`: An instance or list of `starlite.config.StaticFilesConfig`. See [static files](./3-static-files.md).
Expand Down
12 changes: 11 additions & 1 deletion docs/usage/0-the-starlite-app/1-startup-and-shutdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,22 @@ from typing import cast

from sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine
from starlite import Starlite, State
from pydantic import BaseSettings


class AppSettings(BaseSettings):
POSTGRES_CONNECTION_STRING: str


settings = AppSettings()


def get_postgres_connection(state: State) -> AsyncEngine:
"""Returns the Postgres connection. If it doesn't exist, creates it and saves it in on the application state object"""
if not state.postgres_connection:
state.postgres_connection = create_async_engine(settings.DATABASE_URI)
state.postgres_connection = create_async_engine(
settings.POSTGRES_CONNECTION_STRING
)
return cast(AsyncEngine, state.postgres_connection)


Expand Down
4 changes: 2 additions & 2 deletions docs/usage/1-routing/2-routers.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ The `starlite.router.Router` constructor also accepts the following kwargs:
- `after_response`: A [after response lifecycle hook handler](../13-lifecycle-hooks.md#after-response).
- `before_request`: A [before request lifecycle hook handler](../13-lifecycle-hooks.md#before-request).
- `dependencies`: A dictionary mapping dependency providers. See [dependency-injection](../6-dependency-injection.md).
- `exception_handlers`: A dictionary mapping exceptions or exception codes to handler functions. See [exception-handlers](../../17-exceptions#exception-handling).
- `exception_handlers`: A dictionary mapping exceptions or exception codes to handler functions. See [exception-handlers](../17-exceptions#exception-handling).
- `guards`: A list of guard callable. See [guards](../9-guards.md).
- `middleware`: A list of middlewares. See [middleware](../7-middleware.md).
- `parameters`: A mapping of parameters definition that will be available on all sub route handlers. See [layered parameters](../3-parameters.md#layered-parameters).
- `parameters`: A mapping of parameters definition that will be available on all sub route handlers. See [layered parameters](../3-parameters/4-layered-parameters.md).
- `response_class`: A custom response class to be used as the app's default. See [using-custom-responses](../5-responses.md#using-custom-responses).
- `response_headers`: A dictionary of `ResponseHeader` instances. See [response-headers](../5-responses.md#response-headers).
- `tags`: A list of tags to add to the openapi path definitions defined on the router. See [open-api](../12-openapi.md).
4 changes: 2 additions & 2 deletions docs/usage/1-routing/3-controllers.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ Aside from the `path` class variable see above, you can also also define the fol
- `after_response`: A [after response lifecycle hook handler](../13-lifecycle-hooks.md#after-response).
- `before_request`: A [before request lifecycle hook handler](../13-lifecycle-hooks.md#before-request).
- `dependencies`: A dictionary mapping dependency providers. See [dependency-injection](../6-dependency-injection.md).
- `exception_handlers`: A dictionary mapping exceptions or exception codes to handler functions. See [exception-handlers](../../17-exceptions#exception-handling).
- `exception_handlers`: A dictionary mapping exceptions or exception codes to handler functions. See [exception-handlers](../17-exceptions#exception-handling).
- `guards`: A list of guard callable. See [guards](../9-guards.md).
- `middleware`: A list of middlewares. See [middleware](../7-middleware.md).
- `parameters`: A mapping of parameters definition that will be available on all sub route handlers. See [layered parameters](../3-parameters.md#layered-parameters).
- `parameters`: A mapping of parameters definition that will be available on all sub route handlers. See [layered parameters](../3-parameters/4-layered-parameters.md).
- `response_class`: A custom response class to be used as the app's default. See [using-custom-responses](../5-responses.md#using-custom-responses).
- `response_headers`: A dictionary of `ResponseHeader` instances. See [response-headers](../5-responses.md#response-headers).
- `tags`: A list of tags to add to the openapi path definitions defined on the router. See [open-api](../12-openapi.md).
79 changes: 39 additions & 40 deletions docs/usage/10-plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,52 +206,51 @@ from pydantic import BaseModel


class MyClass:
"""
The class for which we create a plugin. For example, could be a base ORM class such as "Model" or "Document" etc.
"""

...


def to_pydantic_model_class(
self, model_class: Type[MyClass], **kwargs: Any
) -> Type[BaseModel]:
"""
Given a model_class T, convert it to a subclass of the pydantic BaseModel
"""
...


@staticmethod
def is_plugin_supported_type(value: Any) -> bool:
"""
Given a value of indeterminate type, determine if this value is supported by the plugin by returning a bool.
"""
...


def from_pydantic_model_instance(
self, model_class: Type[MyClass], pydantic_model_instance: BaseModel
) -> T:
class MyPlugin:
"""
Given an instance of a pydantic model created using a plugin's 'to_pydantic_model_class',
return an instance of the class from which that pydantic model has been created.
This class is passed in as the 'model_class' kwarg.
The class for which we create a plugin. For example, could be a base ORM class such as "Model" or "Document" etc.
"""
...


def to_dict(self, model_instance: MyClass) -> Dict[str, Any]:
"""
Given an instance of a model supported by the plugin, return a dictionary of serializable values.
"""
...


def from_dict(self, model_class: Type[MyClass], **kwargs: Any) -> MyClass:
"""
Given a class supported by this plugin and a dict of values, create an instance of the class
"""
...
def to_pydantic_model_class(
self, model_class: Type[MyClass], **kwargs: Any
) -> Type[BaseModel]:
"""
Given a model_class T, convert it to a subclass of the pydantic BaseModel
"""
...

@staticmethod
def is_plugin_supported_type(value: Any) -> bool:
"""
Given a value of indeterminate type, determine if this value is supported by the plugin by returning a bool.
"""
...

def from_pydantic_model_instance(
self, model_class: Type[MyClass], pydantic_model_instance: BaseModel
) -> T:
"""
Given an instance of a pydantic model created using a plugin's 'to_pydantic_model_class',
return an instance of the class from which that pydantic model has been created.
This class is passed in as the 'model_class' kwarg.
"""
...

def to_dict(self, model_instance: MyClass) -> Dict[str, Any]:
"""
Given an instance of a model supported by the plugin, return a dictionary of serializable values.
"""
...

def from_dict(self, model_class: Type[MyClass], **kwargs: Any) -> MyClass:
"""
Given a class supported by this plugin and a dict of values, create an instance of the class
"""
...
```
31 changes: 26 additions & 5 deletions docs/usage/11-data-transfer-objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class MyClassDTO(BaseModel):
third: int
```

2. You can remap name and type. To do this use a tuple instead of a string for the object value:
You can remap name and type. To do this use a tuple instead of a string for the object value:

```python
from pydantic import BaseModel
Expand Down Expand Up @@ -208,6 +208,7 @@ PartialCompanyDTO = Partial[CompanyDTO]
The created `PartialCompanyDTO` is equivalent to the following declaration:

```python
from typing import Optional
from pydantic import BaseModel


Expand All @@ -220,12 +221,16 @@ class PartialCompanyDTO(BaseModel):
`Partial` can also be used inline when creating routes.

```python
from pydantic import UUID4
from pydantic import UUID4, BaseModel
from starlite.controller import Controller
from starlite.handlers import patch
from starlite.types import Partial

from my_app.orders.models import UserOrder

class UserOrder(BaseModel):
order_id: UUID4
order_item_id: UUID4
notes: str


class UserOrderController(Controller):
Expand Down Expand Up @@ -277,12 +282,28 @@ When you have an instance of a DTO model, you can convert it into a model instan

```python
from starlite import get
from sqlalchemy import Column, Float, Integer, String
from sqlalchemy.orm import declarative_base
from starlite import DTOFactory
from starlite.plugins.sql_alchemy import SQLAlchemyPlugin

dto_factory = DTOFactory(plugins=[SQLAlchemyPlugin()])

Base = declarative_base()


class Company(Base):
id = Column(Integer, primary_key=True)
name = Column(String)
worth = Column(Float)


CompanyDTO = dto_factory("CompanyDTO", Company)


@get()
def create_company(data: CompanyDTO) -> Company:
company_instance = data.to_model_instance()
...
return data.to_model_instance()
```

In the above `company_instance` is an instance of the SQL Alchemy class `Company`. It is correctly typed as Company
Expand Down
9 changes: 6 additions & 3 deletions docs/usage/12-openapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ If you would like to modify the base path, add new endpoints, change the styling

For example, lets say we wanted to change the base path from "/schema" to "/api-docs":

```python title="my_app/openapi.py"
```python
from starlite import OpenAPIController


Expand All @@ -149,9 +149,12 @@ The following extra attributes are defined on this controller and are customizab
We would then use the subclassed controller like so:

```python
from starlite import Starlite, OpenAPIConfig
from starlite import Starlite, OpenAPIConfig, OpenAPIController


class MyOpenAPIController(OpenAPIController):
path = "/api-docs"

from my_app.openapi import MyOpenAPIController

app = Starlite(
route_handlers=[...],
Expand Down
Loading

0 comments on commit 40cc308

Please sign in to comment.