Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Master branch: |Build Status|
.. |Build Status| image:: https://travis-ci.org/khamin/redisca.png?branch=master :target: https://travis-ci.org/khamin/redisca
Using PyPi (recommended):
::
sudo pip install redisca
or
::
wget https://pypi.python.org/packages/source/r/redisca/redisca-X.tar.gz
tar xvf redisca-X.tar.gz
sudo python redisca-X/setup.py install
.. code:: python
from redisca import Model from redisca import Email from redisca import DateTime
class User (Model): email = Email( field='eml', # Define link with 'eml' hash key. index=True, # Index support. unique=True, # Makes sure that field is unique across db. )
created = DateTime(
field='created', # Define link with 'created' hash key.
new=datetime.utcnow, # Value which is used as default in User.new()
)
age = Integer(
field='age', # Define link with 'age' hash key.
index=True, # Enable index.
)
user = User.new() # Create model with random id and "new" fields values. user = User.new(model_id='your_id') # Or use custom id if needed.
user.getid() # user id user.email = 'foo@bar.com'
user.save() # Saving routines user.exists() # True
user.delete() # Deletion routines user.exists() # False
Field is the way how you should control data in your models. Just define class variables with field-specific options and take classic ORM's advantages:
Available parameters:
Built-in fields:
Using id
Here is an example how to get model instance using id *(empty model returned if it not exists yet)*:
.. code:: python
user = User('user id')
print(user.email) # 'foo@bar.com'
Each initialized model is saved in registry and returned on each attempt of re-init:
.. code:: python
user1 = User('user_id')
user2 = User('user_id')
user1 is user2 # Always is True
user.free() # Unregister model instance.
User.free_all() # Cleanup User's registry.
Model.free_all() # Unregister all known models.
Find by Index
.. code:: python
users = User.email == 'foo@bar.com' # or User.email.find('foo@bar.com')
Subclasses of RangeIndexField has a limited support for ranged queries:
.. code:: python
users = User.age >= 10 # User.age.range(minval=10)
More complex queries are also possible:
.. code:: python
# SELECT * FROM `users` where `age` BETWEEN 0 AND 100 LIMIT 10 OFFSET 50;
users = User.age.range(minval=0, maxval=100, start=50, num=10)
Dict API
All fields are linked to model dict keys. Use can use model dict API to read and write *redis hash* data AS IS:
.. code:: python
user = User('id')
user['eml'] = 'foo@bar.com'
user['age'] = 10
Connecting to Redis
-------------------
Global database connection setup looks like this:
.. code:: python
from redisca import conf
from redis import Redis
conf.db = Redis()
**Note:** *redisca* uses localhost:6379(0) as default database. You can setup **inheritable** per-model database connection using *conf* class decorator:
.. code:: python
from redisca import Model
from redisca import conf
from redis import Redis
@conf(db=Redis())
class User (Model):
pass
Key Format
----------
Model key format is:
::
model_key_prefix:model_id
Default model\_key\_prefix is *lowercased class name*. Use *conf* class decorator to override it like this:
.. code:: python
from redisca import Model
from redisca import conf
@conf(prefix='usr')
class User (Model):
pass
print(User.getprefix()) # 'usr'
print(user.getkey()) # 'usr:1'
Tools
=====
ID Generator
------------
.. code:: python
from redisca import hexid
from redisca import intid
print(hexid()) # 59d369790
print(hexid()) # 59d3697bc
print(intid()) # 24116751882
print(intid()) # 24116788848
Flask Support
-------------
.. code:: python
from redisca import FlaskRedisca
app = Flask()
app.config['REDISCA'] = {
# redis.StrictRedis constructor kwargs dict.
}
FlaskRedisca(app)
Optional *autosave* constructor parameter tells *redisca* that all known models should be saved at the end of request (if no exception raised). Unchanged and deleted instances are ignored. If you want to skip locally changed instances use free() method during request life.
Requirements
============
- redis-py 2.7+
- python 2.7/3.2+ or pypy 2.1+
Python 3.x support
------------------
Py3k support is still a sort of experiment but I'm looking carefuly into full compability with cutting-edge builds of CPython. There are no known issues with it actually.
FAQs
Lightweight ORM for Redis
We found that redisca demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.