Skip to main content

A high-performance, functional asynchronous networking framework.

Project description

classy

  • Release: 1.5.0
  • Webserver (https://, http://)
  • Json (WIP)
  • Error handling (WIP)
  • database intergation & mysql, postgres:
    • Async
    • ARMQ (Async Request Multiple Query)
  • Rate limiter
  • Authentication
  • Schema for JSON (Java Script Object Notation)
  • XSS/CSP and CORS
  • Plugins (Providers)

SSL Support

  • Yes there is ssl support to use ssl you have to do this:
from classy import server

start(use_ssl=True, keyfile="keyfile.pem", certfile="certfile.pem")
  • You will need to generate 2 pem files using openssl.

Create your own server!

  • start a server:
import os
import json
import asyncio
from aiohttp import web
import classy.server
import classy.database

config = {
    "host": "localhost",
    "port": 9880,
    "user": "root",
    "password": os.getenv("SQLpassword"),
    "database": "user"
}

Database = classy.database.Db(etype="mysql", config=config)

await Database.connect()

@classy.server.endpoint_GET("/api/user/{AnimalModelNumber:int}")
async def getuser_animalmodel(request: web.Request, kwargs):
    AnimalModelNumber = kwargs['AnimalModelNumber']
	query_string = "SELECT * FROM users WHERE ip_address = %s AND animal_number = %s"
    query_params = (request.remote, AnimalModelNumber)
    user_animal = await Database.query(query_string, params=query_params)
    return web.json_response(user_animal)


@classy.server.endpoint_POST("/api/user")
async def userget(request):
    headers = {
        "X-User": "User"
    }
    
    user_data = await Database.query(
        "SELECT * FROM users WHERE ip_address = %s;", 
        params=(request.remote,)
    )
    
    return web.Response(
        text=json.dumps(user_data),
        headers=headers,
        content_type="application/json"
    )

async def main():
    await Database.connect()
    classy.server.start(default_folder="public")

if __name__ == "__main__":
    asyncio.run(main())

Server && Microservice communication with HTTP(S)

  • use webresource function in classy.client:
import classy.client

status, text = await classy.client.webresource("GET", "http://transcat.stripe-middle_end-server.local/current")

# ... Execute your business logic ...

# end
classy.client.close_webresource_pool()

Authentication

import classy

def auth_func(request):
	# ... code ...
	if authkeyValidated:
		return True # Let user pass
	return False # Block user

@server.endpoint_POST("/api/v3/user-authed")
@auth.require_auth(auth_func)
def userauthed(request):
	return web.Response(
		text="You shall pass!"
	)

Input sanitization

import classy
from aiohttp import web

def auth_func(request):
	# ... code ...
	if authkeyValidated:
		return True # Let user pass
	return False # Block user

@server.endpoint_POST("/api/v3/user-authed")
@auth.require_auth(auth_func)
@vcatch.preventv() # Sanatizes the body into request['sanitized_data'], adds XSS,CSP Headers automatically
def userauthed(request):
	return web.Response(
		text="You shall pass!"
	)
  • the preventv decorator prevents any XSS injection attempts

Database

  • Example: Delete Alice user from MyApp_Db Database:
     import asyncio
     from classy.database import Db
    
     config = {
     	"host": "localhost",
     	"port": 9880,
     	"user": "root",
     	"password": "1234567890",
     	"database": "MyApp_Db"
     }
    
     async def run():
     	try:
     		db = Db(etype="mysql", config=config)
     		await db.connect()
    
     		sql = "DELETE FROM users WHERE name = %s"
     		target_user = ("Alice",)
    
     		await db.query(sql, target_user, autocommit=True)
     		print("User Alice successfully deleted.")
    
     	except Exception as error:
     		print(f"Framework Database Error during execution: {error}")
     	finally:
     		if 'db' in locals():
     			await db.close()
    
     asyncio.run(run())
    
    • Async code
    • Autocommiting and rollbacks
  • Example: Use ARMQ:
     results = await db.query_armq({
     	"users": "SELECT * FROM users",
     	"target_post": ("SELECT * FROM posts WHERE id = $1", (1,)),
     	"comments": ["SELECT * FROM comments"]
     })
    
    • Get multiple results in one function!
    • result:
       {
       	"users": [
       		(1, "Alice"), 
       		(2, "Bob")
       	],
       	
       	"target_post": [
       		(1, "Hello World")
       	],
       	
       	"comments": [
       		(1, "Nice post")
       	]
       }
      

Add a Plugin (Provider)

  • This is a set it and forget it method!
  • The only thing you need to remember is the classid
  • Example:
from aiohttp import web
from classy import server
from classy.provider import extend, run, Provider

class MemCache(Provider):
	def __init__(self):
		super().__init__("MemCache", [{"disk": False}, {"network": False}])
		self._store = {}

	def __proc_set_value(self):
		return [{"disk": False}, {"network": False}]

	def set_value(self, key: str, val: str):
        self._store[key] = val
        return True

id = extend(MemCache())
run(id).set_value("Authed", "no")
  • Features:

    • Global, can be accessed once defined and extend()ed
    • The extension lives after function dies
    • Supports seamless modular distribution. Third-party developers can package extensions cleanly following naming conventions like:
      • Official extensions: firepy-aioclassy-extender-xyz
      • Community extensions: user-classy-extender-xyy
  • Example:

pip install firepy-aioclassy-extender-xyzplug

and now:

from aiohttp import web
from classy.server import endpoint_GET, start
from classy.server import extend, run
from xyzplug.plugin1 import WebApiProvider

id = extend(WebApiProvider())
run(id).func()

Rate limiter

  • The ratelimiter uses 'Cost Based Token Bucket RateLimiter' Method
  • Use it via decorators:
from classy.rate import rate_limit
from aiohttp import web
import asyncio

MAX_TOKENS = 150
MAX_REFILL_PERIOD = 10

@endpoint_GET("/api/make-system-status-report")
@rate_limit(MAX_TOKENS, MAX_REFILL_PERIOD, minus_token_amount=60)
async def make_system_report(request):
	# Do the report thing

	return web.Response(
		text=jsontext,
		content_type="application/json"
	)


asyncio.run(start())

Schema

  • Implementation for Schema:
from classy.schema import Schema, validate_schema
from classy.server import endpoint_POST, start
from aiohttp import web

class Body(Schema):
	# ...

class Head(Schema):
	# ...

class Tail(Schema):
	# ...

class Hair(Schema):
	# ...

class Legs(Schema):
	# ...

class Model(Schema):
	Hasbody: bool
	Hashead: bool
	Hastail: bool
	Hashair: bool
	Haslegs: bool
	body: Body
	head: Head
	tail: Tail
	hair: Hair
	Legs: Legs

@endpoint_POST("/api/v2/save-animal-to-profile")
@validate_schema(Model)
def save_animal_to_profile(request: web.Request, kwargs):
	# Save to Database
	# ... code ...
    # kwargs['body'] is the Schema/JSON

	if success:
		return web.json_response({ "success": True })

	return web.json_response({ "success": False })
  • Malformed JSON Requests can crash your server. So, you always need a Schema in the behind the scenes

Questions

    1. What is ARMQ?
    • => It is a feature in the database module of classy used to get multiple results at the same time
    1. Why use classes for Db?
    • => We use classes for Db because instead of passing in multiple varibles for it to work, you dont even need to pass in the conn or cursor varibles. You just pass in the query!
    1. Why do REST and Static file serving?
    • => We integrate REST and Static file serving because instead of choosing two Static file serving, REST Frameworks and having to intertwine them you can just do them both
    1. What is authentication anyways?
    • => Authentication (AuthN) is the cryptographic or logical process of proving you are who you say you are.

Contributing

  • Any contributions to this project are warmly welcomed
  • Requirements:
    • No malware, trojans, ransomware etc... if we find malware in your code we will report your user.
    • No vulnerabilities, if we have found a vulnerability then we will deny the request immediatly!
    • Code quality: you must follow:
      • the DRY rule (Dont repeat youself)
    • Ai vibe code: ZERO, if we find vibe coded slop we will PERMENENTLY STOP TAKING REQUESTS FROM YOU
    • If you pass all the above you can start forking and pull-requesting by next Week.

Security

  • WE TAKE SECURITY SEROUSLY HERE!!!!!!
  • as mentioned before you must have not malware, vulnerabilities and ai coded vibe slop!!!

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

firepy_aioclassy-1.5.0.tar.gz (31.5 kB view details)

Uploaded Source

Built Distribution

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

firepy_aioclassy-1.5.0-py3-none-any.whl (30.0 kB view details)

Uploaded Python 3

File details

Details for the file firepy_aioclassy-1.5.0.tar.gz.

File metadata

  • Download URL: firepy_aioclassy-1.5.0.tar.gz
  • Upload date:
  • Size: 31.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for firepy_aioclassy-1.5.0.tar.gz
Algorithm Hash digest
SHA256 fa51b6a7686bc9f06b769daf6c6f279b3046acef0d80e064901d669fe19c168c
MD5 8e69460c2ef4b6138316675a11b2dae6
BLAKE2b-256 c39c0f838abecf5833fcbe38f2e6186b7ef533dc8a3bec77330be705299efdbd

See more details on using hashes here.

File details

Details for the file firepy_aioclassy-1.5.0-py3-none-any.whl.

File metadata

File hashes

Hashes for firepy_aioclassy-1.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f85f156075082bbeff22a57514addc9bb7aa5f272317e0cd76357bd943de8687
MD5 8a5782c77c6cf9ad782bf0bba47e9ff7
BLAKE2b-256 0262973f07bf903b68bf64461f8531a5177e0c61cabf5991bf06ce5063be355a

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