Skip to content

Commit

Permalink
72 expressions improvements (#117)
Browse files Browse the repository at this point in the history
* Renamed statement as expression

* Renamed expression as operand

* Renamed resolve as express

* expression -> operand

* follow up

* Fixed tests

* Added mypy.ini and updated gitignore

* Replaced old dict typehints by Expression

* Follow up

* Replaced dict typehint by Expression in operators

* Follow up for search operators

* FIXME : Fix lookup, join, right join and associated tests following collection removal in pipeline

* Removed right joins

* Removed old expressions module

* Fixed test
  • Loading branch information
VianneyMI committed Apr 23, 2024
1 parent 733c372 commit 3bb0933
Show file tree
Hide file tree
Showing 101 changed files with 644 additions and 1,203 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
venv
.venv
.coverage
.env
notes.md
**/*~
Expand Down
5 changes: 2 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ import os

from dotenv import load_dotenv
import pymongo
from monggregate import Pipeline, S, Expression
from monggregate import Pipeline, S

# Creating connexion string securely
load_dotenv(verbose=True)
Expand All @@ -142,8 +142,7 @@ client = pymongo.MongoClient(MONGODB_URI)
db = client["sample_mflix"]

# Using expressions
comments_count = Expression.field("comments").size()

comments_count = S.size(S.comments)

# Creating the pipeline
pipeline = Pipeline()
Expand Down
9 changes: 9 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[mypy]
show_column_numbers = True
implicit_optional = False
disallow_untyped_defs = True
disallow_untyped_calls = True
follow_imports = silent
ignore_missing_imports = True
plugins = pydantic.mypy
explicit_package_bases = True
5 changes: 2 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ import os

from dotenv import load_dotenv
import pymongo
from monggregate import Pipeline, S, Expression
from monggregate import Pipeline, S

# Creating connexion string securely
load_dotenv(verbose=True)
Expand All @@ -142,8 +142,7 @@ client = pymongo.MongoClient(MONGODB_URI)
db = client["sample_mflix"]

# Using expressions
comments_count = Expression.field("comments").size()

comments_count = S.size(S.comments)

# Creating the pipeline
pipeline = Pipeline()
Expand Down
3 changes: 1 addition & 2 deletions src/monggregate/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
"""App Package"""

from monggregate.expressions import Expression
from monggregate.dollar import S, SS
from monggregate.pipeline import Pipeline

__all__ = ["Expression", "S", "SS", "Pipeline"]
__all__ = ["Pipeline", "S", "SS"]

__version__ = "0.21.0"
__author__ = "Vianney Mixtur"
Expand Down
16 changes: 0 additions & 16 deletions src/monggregate/_run.py

This file was deleted.

32 changes: 20 additions & 12 deletions src/monggregate/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@
#----------------------------
from abc import ABC, abstractmethod
from typing import Any, TypeGuard
from typing_extensions import Self


# 3rd Party imports
# ---------------------------
try:
import pydantic.v1 as pyd
except ModuleNotFoundError:
import pydantic as pyd
import pydantic as pyd # type: ignore[no-redef]


from humps.main import camelize
Expand All @@ -24,32 +25,39 @@ class Singleton:
"""Singleton metaclass"""

_instance = None
def __new__(cls, *args, **kwargs):
def __new__(cls, *args:Any, **kwargs:Any)->Self:
if not isinstance(cls._instance, cls):
cls._instance = object.__new__(cls, *args, **kwargs)
return cls._instance

Expression = dict[str, Any]

class BaseModel(pyd.BaseModel, ABC):
"""Mongreggate base class"""

def to_expression(self)->Expression|list[Expression]:
"""Converts an instance of a class inheriting from BaseModel to an expression"""

return self.express(self)

@classmethod
def resolve(cls, obj:Any)->dict|list[dict]:
def express(cls, obj:Any)->Expression|list[Expression]:
"""Resolves an expression encapsulated in an object from a class inheriting from BaseModel"""

return resolve(obj)
return express(obj)

@property
@abstractmethod
def statement(self)->dict:
def expression(self)->Expression:
"""Stage statement absctract method"""

# this is a lazy attribute
# what is currently in generate statement should go in here

def __call__(self)->dict:
def __call__(self)->Expression|list[Expression]:
"""Makes an instance of any class inheriting from this class callable"""

return self.resolve(self.statement)
return self.to_expression()

class Config(pyd.BaseConfig):
"""Base configuration for classes inheriting from this"""
Expand All @@ -65,25 +73,25 @@ def isbasemodel(instance:Any)->TypeGuard[BaseModel]:

return isinstance(instance, BaseModel)

def resolve(obj:Any)->dict|list[dict]:
def express(obj:Any)->dict|list[dict]:
"""Resolves an expression encapsulated in an object from a class inheriting from BaseModel"""

if isbasemodel(obj):
output:dict|list = obj.statement
output:dict|list = obj.expression
elif isinstance(obj, list) and any(map(isbasemodel, obj)):
output = []
for element in obj:
if isinstance(element, BaseModel):
output.append(element.statement)
output.append(element.expression)
else:
output.append(element)
elif isinstance(obj, dict):
output = {}
for key, value in obj.items():
if isinstance(value, BaseModel):
output[key] = value.statement
output[key] = value.expression
else:
output[key] = resolve(value)
output[key] = express(value)
else:
output = obj

Expand Down
Loading

0 comments on commit 3bb0933

Please sign in to comment.