Skip to content

Commit

Permalink
Merge pull request #392 from candango/develop
Browse files Browse the repository at this point in the history
Merging develop to master
  • Loading branch information
piraz committed Jan 30, 2022
2 parents 8d33196 + d8ac63b commit 79937cf
Show file tree
Hide file tree
Showing 21 changed files with 380 additions and 47 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright 2015-2020 Flavio Garcia
Copyright 2015-2022 Flávio Gonçalves Garcia

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
18 changes: 8 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
# Firenado Framework

**master:** [![Build Status](https://travis-ci.org/candango/firenado.svg?branch=master)](https://travis-ci.org/candango/firenado)
[![Code Health](https://landscape.io/github/candango/firenado/master/landscape.svg?style=flat)](https://landscape.io/github/candango/firenado/master)
[![Documentation Status](https://readthedocs.org/projects/firenado/badge/?version=latest)](https://readthedocs.org/projects/firenado/?badge=latest)

**develop:** [![Build Status develop](https://travis-ci.org/candango/firenado.svg?branch=develop)](https://travis-ci.org/candango/firenado)
[![Code Health](https://landscape.io/github/candango/firenado/develop/landscape.svg?style=flat)](https://landscape.io/github/candango/firenado/develop)
[![Documentation Status](https://readthedocs.org/projects/firenado/badge/?version=develop)](http://firenado.readthedocs.org/en/develop/?badge=develop)

[![Latest PyPI version](https://img.shields.io/pypi/v/firenado.svg)](https://pypi.org/project/firenado/)
[![Number of PyPI downloads](https://img.shields.io/pypi/dm/firenado.svg)](https://pypi.org/project/firenado/)
[![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fcandango%2Ffirenado%2Fbadge&style=flat)](https://actions-badge.atrox.dev/candango/firenado/goto)
[![GitHub license](https://img.shields.io/github/license/candango/firenado)](https://github.com/candango/firenado/blob/develop/LICENSE)

## Introduction

Expand Down Expand Up @@ -93,8 +89,10 @@ app:

## Support

Firenado is one of [Candango Open Source Group](http://www.candango.org/projects/) initiatives. It is available under
the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html).
Firenado is one of [Candango Open Source Group
](http://www.candango.org/projects/) initiatives. It is available under
the [Apache License, Version 2.0
](http://www.apache.org/licenses/LICENSE-2.0.html).

This web site and all documentation is licensed under [Creative
Commons 3.0](http://creativecommons.org/licenses/by/3.0/).
29 changes: 29 additions & 0 deletions docs/.readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

# Required
version: 2

# Set the version of Python and other tools you might need
build:
os: ubuntu-20.04
tools:
python: "3.9"
# You can also specify other tool versions:
# nodejs: "16"
# rust: "1.55"
# golang: "1.17"

# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py

# If using Sphinx, optionally build your docs in additional formats such as PDF
# formats:
# - pdf

# Optionally declare the Python requirements required to build your docs
python:
install:
- requirements: requirements/docs.txt
8 changes: 4 additions & 4 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
source_suffix = ['.rst', '.md']

# The encoding of source files.
#source_encoding = 'utf-8-sig'
Expand All @@ -47,8 +47,8 @@

# General information about the project.
project = u'Firenado Framework'
copyright = u'2015-2020, Flavio Garcia'
author = u'Flavio Garcia'
copyright = u'2015-2020, Flávio Gonçalves Garcia'
author = u'Flávio Gonçalves Garcia'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
Expand All @@ -57,7 +57,7 @@
# The short X.Y version.
version = '0.2'
# The full version, including alpha/beta/rc tags.
release = '0.2.14'
release = '0.2.15'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
46 changes: 46 additions & 0 deletions docs/guide/services.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
Services
========

The way firenado organizes the logic to be executed in several parts of an
application is defining services.

Those services can be injected with the decorator
``firenado.service.served_by``. This decorator will add an instance of a
service to a method of any data connected object. Examples of data connected
classes are ``firenado.tornadoweb.TornadoHandler`` and any descendent of
``firenado.service.FirenadoService``.

Creating a service and decorating a handler:

.. code-block:: python
from firenado import service, tornadoweb
# Importing a package with some services
import another_service_package
class MyService(service.FirenadoService):
def do_something(self):
# Self consumer will be the handler where this service was
# called from.
self.consumer.write("Something was done")
class MyHandlerBeingServed(tornadoweb.TornadoHandler):
# A good way to keep the reference is keeping the type hint
my_service: MyService
service_from_another_package: another_service_package.AnotherService
@service.served_by(MyService)
# you can also set the attribute/property name to be used
@service.served_by(another_service_package.AnotherService,
attribute_name="service_from_another_package"
)
def get(self):
# The anotation service.served_by added self.my_service
# here. The attribute/property name will be converted from the
# cammel cased class to dashed separated.
self.my_service.do_something()
self.service_from_another_package.do_another_thing()
You can also add services to another services using the decorator:
1 change: 1 addition & 0 deletions docs/releases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Release notes
.. toctree::
:maxdepth: 2

releases/v0.2.15
releases/v0.2.14
releases/v0.2.13
releases/v0.2.12
Expand Down
23 changes: 23 additions & 0 deletions docs/releases/v0.2.15.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
What's new in Firenado 0.2.15
=============================

Jan 30, 2022
------------

We are pleased to announce the release of Firenado 0.2.15.

At this release we added a service decorator to help handle sqlalchemy
sessions.

Here are the highlights:

Bug Fixes
~~~~~~~~~

* Change dashed parameters to underscored ones in setup.cfg. `#385 <https://github.com/candango/firenado/issues/385>`_

Features
~~~~~~~~

* Create a decorator to handle shared sqlalchemy sessions between mehtods. `#377 <https://github.com/candango/firenado/issues/377>`_
* Add shortcut properties to help get components from the scheduler and scheduled job. `#387 <https://github.com/candango/firenado/issues/387>`_
8 changes: 5 additions & 3 deletions firenado/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: UTF-8 -*-
#
# Copyright 2015-2022 Flavio Garcia
# Copyright 2015-2022 Flávio Gonçalves Garcia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -17,12 +17,14 @@

"""The Firenado Framework"""

__author__ = "Flavio Garcia <piraz@candango.org>"
__version__ = (0, 2, 14)
__author__ = "Flávio Gonçalves Garcia <piraz at candango.org>"
__version__ = (0, 2, 15)
__licence__ = "Apache License V2.0"


def get_version():
if isinstance(__version__[-1], str):
return '.'.join(map(str, __version__[:-1])) + __version__[-1]
return ".".join(map(str, __version__))


Expand Down
2 changes: 1 addition & 1 deletion firenado/bin/firenado-cli.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
# Copyright 2015-2019 Flavio Garcia
# Copyright 2015-2022 Flávio Gonçalves Garcia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion firenado/data.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: UTF-8 -*-
#
# Copyright 2015-2021 Flavio Goncalves Garcia
# Copyright 2015-2022 Flávio Gonçalves Garcia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
26 changes: 24 additions & 2 deletions firenado/schedule.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: UTF-8 -*-
#
# Copyright 2015-2021 Flavio Garcia
# Copyright 2015-2022 Flávio Gonçalves Garcia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -71,6 +71,14 @@ def __init__(self, component, **kwargs):
self.component = component
self._periodic_callback = None

@property
def app_component(self) -> TornadoComponent:
""" Shortcut to self.component.app_component
:return: TornadoComponent
"""
return self.component.app_component

@property
def id(self):
return self._id
Expand All @@ -84,7 +92,9 @@ def name(self):
return self._name

@property
def can_run(self):
def can_run(self) -> bool:
""" Indicates if the scheduler can run
"""
return self._can_run

def add_job(self, job):
Expand Down Expand Up @@ -239,6 +249,18 @@ def __init__(self, scheduler, **kwargs):
self._interval = kwargs.get('interval')
self._periodic_callback = None

@property
def component(self) -> "ScheduledTornadoComponent":
""" Return scheduler's component
"""
return self._scheduler.component

@property
def app_component(self) -> TornadoComponent:
""" Shortcut to self.component.app_component
"""
return self.component.app_component

@property
def id(self):
return self._id
Expand Down
61 changes: 60 additions & 1 deletion firenado/service.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: UTF-8 -*-
#
# Copyright 2015-2021 Flavio Garcia
# Copyright 2015-2022 Flávio Gonçalves Garcia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -16,6 +16,10 @@

import functools
import importlib
import inspect
import logging

logger = logging.getLogger(__name__)


class FirenadoService(object):
Expand Down Expand Up @@ -114,3 +118,58 @@ def wrapper(self, *args, **kwargs):

return wrapper
return f_wrapper


def sessionned(*args, **kwargs):
""" This decorator will add an existing session to the method being
decorated or create a new session to be used by the method."""
service = None
if len(args) > 0:
service = args[0]

def method_wrapper(method):
@functools.wraps(method)
def wrapper(self, *method_args, **method_kwargs):
session = method_kwargs.get("session")
close = kwargs.get("close", False)
close = method_kwargs.get("close", close)
if not session:
data_source = kwargs.get("data_source")
data_source = method_kwargs.get("data_source", data_source)
if not data_source:
hasattr(self, "default_data_source")
if hasattr(self, "default_data_source"):
if inspect.ismethod(self.default_data_source):
data_source = self.default_data_source()
else:
data_source = self.default_data_source
try:
if isinstance(data_source, str):
ds = self.get_data_source(data_source)
method_kwargs['data_source'] = data_source
session = ds.session
else:
print(data_source)
session = data_source.session
method_kwargs['session'] = session
except KeyError:
logger.exception("There is no datasource defined with"
"index \"%s\" related to the service." %
data_source)
result = method(self, *method_args, **method_kwargs)
if close:
if not session:
logger.warning("No session was resolved.")
logger.debug("Closing session %s." % session)
session.close()
return result
return wrapper
# If the decorator has no parameter, I mean no parentesis, we need to wrap
# the service variable again , instead of the service instance, we need to
# deal with the method being decorated but as a <function> instace.
if inspect.isfunction(service):
@functools.wraps(None)
def func_wrapper(_function):
return method_wrapper(_function)
return func_wrapper(service)
return method_wrapper
7 changes: 6 additions & 1 deletion firenado/tornadoweb.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,12 @@ def __init__(self, default_host="", transforms=None, **settings):
else:
logger.debug("Session is disabled.")

def get_app_component(self):
def get_app_component(self) -> "TornadoComponent":
""" Return the component set as the application component at the
app config.
:return: TornadoComponent
"""
return self.components[firenado.conf.app['component']]

def __load_components(self):
Expand Down
1 change: 1 addition & 0 deletions requirements/docs.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
myst_parser>=0.16.1
2 changes: 1 addition & 1 deletion requirements/redis.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
redis==3.5.3
redis==4.1.2
hiredis==2.0.0
2 changes: 1 addition & 1 deletion requirements/schedule.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
croniter==1.0.10
croniter==1.2.0
2 changes: 1 addition & 1 deletion requirements/sqlalchemy.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sqlalchemy==1.4.26
sqlalchemy==1.4.31
2 changes: 1 addition & 1 deletion requirements/tests.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
behave==1.2.6
bandit==1.7.0
bandit>=1.7.0
pymysql==1.0.2
4 changes: 2 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[metadata]
license-file = LICENSE
description-file = README.md
license_file = LICENSE
description_file = README.md
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
# Copyright 2015-2021 Flavio Garcia
# Copyright 2015-2022 Flávio Gonçalves Garcia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down

0 comments on commit 79937cf

Please sign in to comment.