Skip to main content

Yet Another Python Library

Project description

pylib

pylib

                 Python License

A python library that helps writing py projects much easier and faster.

Table of contents

This library covers multiple aspects, including:

Installation

You can simply install this library through pip, via following commad:

python3 -m pip install pylib-0xe

Documentation

I. Config

The Config facade simplifies reading hierarchical JSON config files. Here's how it works:

Usage Example

Assume you have several .json config files or folders with configurations under the configs directory. To access the humans.male.height attribute from mammals.json, use the following code:

Config.read('mammals.humans.male.height')

Default Values

You can specify a default value if the attribute is not found:

Config.read(..., default=180)

Reading Environment Configurations

The read_env property looks for an env.json file in the project's directory hierarchy. Once found, it searches for the specified pattern. For example, to access db.postgres.password, use:

Config.read_env('db.postgres.password')

II. Database

The Database facade provides convenient methods for interacting with databases using SQLAlchemy. Follow these steps to set it up:

Registering a Database Engine

First, register your database engine with the EngineMediator:

from pylib_0xe.database.mediators.engine_mediator import EngineMediator
from pylib_0xe.database.engines.postgres_engine import PostgresEngine

# Register the Postgres engine
EngineMediator().register(DatabaseTypes.I, PostgresEngine().engine)

This associates DatabaseTypes.I with the SQLAlchemy engine.

Note: Ensure your env.json contains the db.postgres configuration:

{
  "db": {
    "postgres": {
      "host": "127.0.0.1",
      "port": 1234,
      "user": "",
      "password": "",
      "db": "",
      "test_db": ""
    }
  }
}

Using Database Sessions

You can inject database sessions into functions using the @db_session decorator:

from typing import Optional
from sqlalchemy import Session
from pylib_0xe.decorators.db_session import db_session
from pylib_0xe.types.database_types import DatabaseTypes

@db_session(DatabaseTypes.I)
def fn(session: Optional[Session] = None):
    session.query(...)

Using the Repository Facade

Alternatively, use the Repository facade for simplified CRUD operations:

from pylib_0xe.repositories.repository import Repository
from src.models.user import User

# 'User' should be a SQLAlchemy model inheriting from DecoratedBase
# 'DecoratedBase' is located in pylib_0xe.database.decorated_base

user = Repository(User).read_by_id("123456")

III. Rabbit-MQ Messaging

The Messaging facade simplifies creating robust RabbitMQ-based messaging projects. It consists of two main components:

  1. Server Side
  2. Client Side

Note: Ensure the message_broker section is included in your env.json file for full functionality:

{
  "message_broker": {
    "host": "127.0.0.1:5672",
    "url": "amqp://127.0.0.1:5672"
  }
}

Both server and client components support asynchronous and blocking connections. Below, we illustrate examples for the asynchronous connection.


Establishing an Async Connection

Use the inject_async_connection decorator to create and inject an async RabbitMQ connection:

from pylib_0xe.decorators.inject_async_connection import inject_async_connection
from pylib_0xe.messaging.rpc.rpc_async_connection import RpcAsyncConnection

@inject_async_connection
def main(connection: Optional[RpcAsyncConnection] = None):
    pass

This decorator creates an async connection and injects it into the main function.


Server Side: Listening to a Queue

On the server side, create a RabbitMQ queue, listen to it, and invoke a callback function when a job is received:

from pylib_0xe.messaging.rpc.rpc_async_server import RpcAsyncServer
from pylib_0xe.asynchrone.get_or_create_event_loop import GetOrCreateEventLoop

# Define the callback function
def resolver(*args, **kwargs):
    pass

@inject_async_connection
def main(connection: Optional[RpcAsyncConnection]):
    # Create the server instance
    RpcAsyncServer(
        routing_key="some-random-q",
        connection=connection,
        query_handler=resolver,
    )

    # Start the event loop
    GetOrCreateEventLoop().get_or_create().run_forever()

This setup ensures that the server listens for messages on the specified routing_key and processes them using the resolver function.


Client Side: Sending Messages

On the client side, send a message to a specific queue using the ClientCaller class:

from pylib_0xe.messaging.client.client_caller import ClientCaller

async def fn():
    return await ClientCaller(
        client_name="some-random-q",
        rpc_connection=connection,
    ).call(input={"query": "generate", "payload": ...})

The ClientCaller sends a message to the some-random-q queue and waits for a response asynchronously.

IV. Json

This facade class helps you operate get and set operations on a json file. Two main functions are:

  1. selector_get_value
  2. selector_set_value

It supports selecting by array indexes (__i) and wild-cards (*) for both set and get methods.

{
  "a": {
    "b": {
      "c": {
        "f": "g"
      }
    },
    "d": [1, 2],
    "e": {},
    "f": [{"g": 123}, {"k": 3}]
  }
}
json_file = File.read_json('file.json')
JsonHelper.selector_get_value(json_file, 'a.b.c.f') # g
JsonHelper.selector_get_value(json_file, 'a.d') # [1, 2]
JsonHelper.selector_set_value(json_file, 'a.f.*.r', 5) # "f": [{"g": 123, "r": 5}, {"k": 3, "r": 5}]
JsonHelper.selector_set_value(json_file, 'a.d.__2', 5) # "d": [1, 5],

V. Buffer IO

This module provides several ways to read, write and edit buffers. You can define file, str and standard-input buffers.

for example you can simply read a whole file like this:

reader = BufferReader(FileBuffer(file_path, "r+"))
while not reader.end_of_buffer():
    line = reader.next_line()

or you can define a string as a buffer and treat it in the same way:

reader = BufferReader(StringBuffer('some awesome text'))
while not reader.end_of_buffer():
    a, b, c = reader.next_int(), reader.next_string(), reader.next_char()

you can also read from standard_input and write to standard_output in this way:

reader = BufferReader(StandardInputBuffer())
writer = BufferWriter(StandardOutputBuffer())
while not reader.end_of_buffer():
    a, b, c = reader.next_int(), reader.next_string(), reader.next_char()
    writer.write_line(f"We have recieved these: ({a}, {b}, {c})")

VI. Data Structures

VII. File

  • File: A class that contains some useful functions to deal with files. Some of them are:
    • read_json(file_path)
    • read_csv(file_path)
    • append_to_file(file_path, string)
    • get_all_files(directory_path, extension)

VIII. Path

  • PathHelper: Provides absolute pathing for the project. Then you can use releative pathing after reaching the project root. As an example:
path = PathHelper.from_root(__file__, 'assets', 'imgs', '1.png')

It will construct the path from the root of the project to the desired file, for this specific example, the file should be accessible under this path: $project_root/assets/imgs/1.png. This function tries to go back from __file__ directory to reach the root directory. The default root directories are src and root. You can specify the root directory name by passing the root_name=YOUR_ROOT_DIR_NAME as a kwarg. Then the above example could be rewritten as something like this:

path = PathHelper.from_root(..., root_name="custom_name")

The best practice to use it with the custom root directory is to write a new PathHelper class that extends PathHelper and apply your custom root_name to it. You can also get rid of __file__ argument in this way. It should be implemented something like this:

from pylib_0xe.path.path_helper import PathHelper as PH


class PathHelper(PH):
  @classmethod
  def root(cls, *path: str) -> str:
    return cls.from_root(__file__, *path, root_name="custom_name")

IX. Argument

  • ArgumentParser: Useful tool to reading arguments passed to a python program executed via command line interface (terminal). for example if you run your program as follow:
python3 main.py --color green --size 2 --fast --O2

you can access the arguments through:

ArgumentParser.get_value('color') -> green
ArgumentParser.get_value('size') -> 2
ArgumentParser.is_option('O2') -> true

X. String

XI. Math

  • Geometry: A neat implemented 2d-geometry library. Some of the usefull functions that it provides are:
    • translate(expression, *points): recieves arithmatic expression and the points afterwards. Returns the answer of the expression. example: translate('* + *.', p1, p2, p3, scalar) = ((p1 * p2) + p3) *. scalar
    • side_sign(p1, p2, p3): Returns in which side of the p1->p2 line, p3 is located.
    • inside_polygon(points, p)
    • segment_intersection(l1, l2)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pylib_0xe-0.1.3.tar.gz (44.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pylib_0xe-0.1.3-py3-none-any.whl (63.5 kB view details)

Uploaded Python 3

File details

Details for the file pylib_0xe-0.1.3.tar.gz.

File metadata

  • Download URL: pylib_0xe-0.1.3.tar.gz
  • Upload date:
  • Size: 44.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.12.3

File hashes

Hashes for pylib_0xe-0.1.3.tar.gz
Algorithm Hash digest
SHA256 84d0e92d1cf0751731c824f5865ce4152d4be59934d3341d875cbf9dacd91f9e
MD5 340500fd27a9fc5d5ee71e81d82f82ae
BLAKE2b-256 a65d704332dd3b3b62c029a25848f0cb8131b84e50156396b7f2870e8be09723

See more details on using hashes here.

File details

Details for the file pylib_0xe-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: pylib_0xe-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 63.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.12.3

File hashes

Hashes for pylib_0xe-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 6ed6c362a2a769ef9ef8dd2378a25a8a5b3db9573aa37762d8eef255d9e6be3d
MD5 a07de70733100929fba48ad7b83af43a
BLAKE2b-256 64ca7a9f0ba47fe5a0d96cd665acaafc6ce36549d576346d3f489f075c6f8aa2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page