Skip to content
This repository was archived by the owner on Sep 2, 2025. It is now read-only.

vlakir/cleanapi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PyPi Version

CleanAPI

Pretty tornado wrapper for making lightweight REST API services


Installation:

pip install cleanapi

Example:

Project folders structure:

.
├── handlers
│   └── simple_handler.py
├── log
├── ssl
│   ├── ca.csr
│   └── ca.key
├── static_html
│   └── index.html
└── server_example.py

server_example.py

from cleanapi import server

if __name__ == '__main__':
    # uses http protocol
    server.start('http', 8080, '/', './handlers', './static_html')

    # # uses https protocol
    # server.start('https', 8443, '/', './handlers', './static_html',
    #              path_to_ssl='./ssl', ssl_certfile_name='ca.csr', ssl_keyfile_name='ca.key')

simple_handler.py

from cleanapi.server import BaseHandler

url_tail = '/example.json'


# noinspection PyAbstractClass
class Handler(BaseHandler):
    """
    Test API request handler
    """
    async def get(self):
        self.set_status(200)
        self.write({'status': 'working'})

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Cleanapy demo</title>
  <link rel="icon" href="/favicon.ico" type="image/x-icon" />
 </head>
<body>

<h1>Cleanapy demo page</h1>

<p>Everything OK</p>

</body>
</html>

You also may put 'favicon.ico' file to the 'static_html' folder, but it is not necessary.

Then you can test server responses on http://localhost:8080 and http://localhost:8080/example.json

See log/cleanapi.log for information about externel access to the server


Example with PydanticHandler:

pydantic_handler.py

from cleanapi.server import PydanticHandler
from pydantic import BaseModel, validator, NonNegativeInt
from typing import Optional, List


url_tail = '/pydantic.json'


class PydanticRequest(BaseModel):
    """
    Pydantic dataclass for request
    """
    foo: NonNegativeInt
    bar: NonNegativeInt

    @validator('foo', 'bar')
    def _validate_foo_bar(cls, val: str):
        if val == 666:
            raise ValueError(f'Values of foo and bar should not be equal to 666')
        return val


class PydanticResponse(BaseModel):
    """
    Pydantic dataclass for response
    """
    summ: Optional[NonNegativeInt]
    errors: Optional[List[dict]]


# noinspection PyAbstractClass
class Handler(PydanticHandler):
    """
    Example of using PydanticHandler
    """
    request_dataclass = PydanticRequest
    result_dataclass = PydanticResponse

    # noinspection PyUnusedLocal
    def process(self, request: request_dataclass) -> result_dataclass:
        """
        What the handler should do
        :param request: incoming request
        :type request: request_dataclass
        :return: processing result
        :type: result_data class
        """
        result = PydanticResponse(summ=request.foo + request.bar, errors=[])

        if result.summ > 1000:
            raise ValueError('The sum of foo and bar is more than 1000')

        return result

    def if_exception(self, errors: list) -> None:
        """
        What to do if an exception was thrown
        :param errors: list of errors
        :type errors: list
        """
        self.set_status(400)
        self.write({'errors': errors})
        return

You can not test it with a browser because of POST method using. You have to use a program like Postman or some custom util like my pynger.py

About

Pretty tornado wrapper for making lightweight REST API services

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors