async def test_exception_in_cache_backend( aiohttp_client: TestClientFixture) -> None: """check if application still works if cache backend is misconfigured or cache backend doesn't work""" handler_hits = 0 @cached async def handler(_: web.Request) -> web.Response: nonlocal handler_hits handler_hits += 1 return web.Response(body=b"Hello world") app = web.Application() app.router.add_route('GET', '/', handler) cache = Cache( Cache.REDIS, endpoint="such.hostname.must.not.exist", serializer=PickleSerializer(), namespace="main", ttl=60, ) register_cache(app, cache) client = await aiohttp_client(app) hits = 10 for i in range(hits): resp = await client.get("/") assert await resp.read() == b"Hello world" assert resp.status == 200 assert handler_hits == hits
def get_app(config: Optional[Config] = None) -> web.Application: if config is None: config = Config() # use default values # could be configurable too, but who need it? charged_words = read_charged_words([ os.path.join(BASE_DIR, "charged_dict/negative_words.txt"), os.path.join(BASE_DIR, "charged_dict/positive_words.txt"), ]) app = web.Application(middlewares=[error_middleware]) app["filter_config"] = config app.add_routes([web.get('/', handle_news_list)]) app.cleanup_ctx.append(aiohttp_client) scorer = ArticlesScorer( charged_words=charged_words, morph=pymorphy2.MorphAnalyzer(), ) app["scorer"] = scorer if config.redis_host: cache_decorator = cached( cache=Cache.REDIS, serializer=PickleSerializer(), endpoint=config.redis_host, port=config.redis_port, namespace="main", ttl=60, ) decorated_rate_article = cache_decorator(score_article) scorer.score_article = decorated_rate_article # use custom strategy return app
def filecache(basedir): # Import from here since these are optional dependencies from aiocache import cached from aiocache.serializers import PickleSerializer from aiofilecache import FileCache return cached(cache=FileCache, serializer=PickleSerializer(), basedir=basedir, timeout=None, key_builder=_key_builder)
def __init__(self, config) -> None: super().__init__( serializer=PickleSerializer(), namespace=config.REDIS_NAMESPACE, endpoint=config.REDIS_IP, port=config.REDIS_PORT, db=config.REDIS_DB, )
class TagsRepository(BaseRepository): @cached(cache=Cache.REDIS, serializer=PickleSerializer(), endpoint=os.environ.get('REDIS_HOST'), key_builder=key_builder) async def get_all_tags(self) -> List[str]: tags_row = await queries.get_all_tags(self.connection) return [tag[0] for tag in tags_row] async def create_tags_that_dont_exist(self, *, tags: Sequence[str]) -> None: await queries.create_new_tags(self.connection, [{"tag": tag} for tag in tags])
def test_get_cache_overrides(self): cache = get_cache( cache=RedisCache, namespace="default", serializer=PickleSerializer(), plugins=BasePlugin(), endpoint="http://...", port=123) assert isinstance(cache, RedisCache) assert cache.endpoint == "http://..." assert cache.port == 123 assert cache.namespace == "default" assert isinstance(cache.serializer, PickleSerializer) assert isinstance(cache.plugins, BasePlugin)
async def test_cache_middleware(aiohttp_client: TestClientFixture) -> None: """ test if cache middleware works and doesn't prevent other middlewares from execution """ handler_hits = 0 before_cache_middleware_hits = 0 after_cache_middleware_hits = 0 @web.middleware async def before_cache_middleware(request: web.Request, handler: Any) -> web.Response: nonlocal before_cache_middleware_hits before_cache_middleware_hits += 1 return await handler(request) @web.middleware async def after_cache_middleware(request: web.Request, handler: Any) -> web.Response: nonlocal after_cache_middleware_hits after_cache_middleware_hits += 1 return await handler(request) @cached async def handler(_: web.Request) -> web.Response: nonlocal handler_hits handler_hits += 1 return web.Response(body=b"Hello world") app = web.Application(middlewares=[before_cache_middleware]) app.router.add_route('GET', '/', handler) cache = Cache( Cache.MEMORY, serializer=PickleSerializer(), namespace="0", ttl=60, ) register_cache(app, cache) # it's artificial case app.middlewares.append(after_cache_middleware) client = await aiohttp_client(app) hits = 10 for i in range(hits): resp: aiohttp.ClientResponse = await client.get("/") assert await resp.read() == b"Hello world" assert resp.status == 200 assert handler_hits == 1 assert after_cache_middleware_hits == 1 assert before_cache_middleware_hits == hits
def test_get_cache_with_default_plugins_kwargs(self): settings.set_cache( "aiocache.RedisCache", endpoint="http://...", port=6379) cache = get_cache( namespace="default", serializer=PickleSerializer(), plugins=BasePlugin(), port=123) assert isinstance(cache, RedisCache) assert cache.endpoint == "http://..." assert cache.port == 123 assert cache.namespace == "default" assert isinstance(cache.serializer, PickleSerializer) assert isinstance(cache.plugins, BasePlugin)
def test_get_cache_overrides(self): cache = get_cache(cache=RedisCache, namespace="default", serializer=PickleSerializer(), policy=DefaultPolicy, endpoint="http://...", port=123) assert isinstance(cache, RedisCache) assert cache._backend.endpoint == "http://..." assert cache._backend.port == 123 assert cache.namespace == "default" assert isinstance(cache.serializer, PickleSerializer) assert isinstance(cache.policy, DefaultPolicy)
def test_get_cache_with_default_config(self): aiocache.settings.set_defaults(cache="aiocache.RedisCache", endpoint="http://...", port=6379) cache = get_cache(namespace="default", serializer=PickleSerializer(), policy=DefaultPolicy, port=123) assert isinstance(cache, RedisCache) assert cache._backend.endpoint == "http://..." assert cache._backend.port == 123 assert cache.namespace == "default" assert isinstance(cache.serializer, PickleSerializer) assert isinstance(cache.policy, DefaultPolicy)
class Wolfram: client: wolframalpha.Client = None def __init__(self, loop, api_key: str): self.loop = loop self.api_key = api_key async def get_client(self): if self.client is None: def _get_client(): return wolframalpha.Client(self.api_key) self.client = await self.loop.run_in_executor(None, _get_client) @cached( ttl=24 * 3600, serializer=PickleSerializer(), cache=Cache.MEMORY, namespace="math", ) async def query(self, query: str) -> Tuple[str, Optional[wolframalpha.Result]]: def _query(): return self.client.query(query) result: wolframalpha.Result = await self.loop.run_in_executor( None, _query) if result.success: return query, result if not hasattr(result, "didyoumean"): return query, None if isinstance(didyoumeans := result.didyoumeans["didyoumean"], list): query = didyoumeans[0]["#text"] else:
class MoviesView(BaseView): """Representation of movie list with people appearing in them. GET /movies """ FILMS_KEY = "films" PEOPLE_KEY = "people" def __init__(self): self.base_url = runtime_config().MOVIE_HOST @cached(ttl=Config.CACHE_DEFAULT_TIMEOUT, key="movies", serializer=PickleSerializer()) async def get(self, request: Request) -> str: """Makes json object with movies data. Args: request: Request object. Returns: Movies with people data. """ movies = await self._get_entity(self.FILMS_KEY) people = await self._get_entity(self.PEOPLE_KEY) movies_with_people = self._enrich_movies_by_people(movies, people) return json(movies_with_people) async def _get_entity(self, entity_name: str) -> List[Dict]: """Makes http request by source entity name. Args: entity_name: resource name. Returns: Response data. """ logging.info(f"Getting movie entity: {entity_name}") request_url = f"{self.base_url}/{entity_name}" return await self.make_get_request(request_url) @classmethod def _enrich_movies_by_people(cls, movies: List[Dict], people: List[Dict]) -> List[Dict]: """Adds people list to movie object. Args: movies: list of movie objects. people: list of movie characters. Returns: List of movies enriched by people appearing in them. """ def add_people_key_to_movie(movie: Dict) -> Dict: movie[cls.PEOPLE_KEY] = [] return movie movies_id_map = { movie["id"]: add_people_key_to_movie(movie) for movie in movies } for person in people: film_ids = list( map(lambda film_uri: film_uri.split("/")[-1], person[cls.FILMS_KEY])) for id in film_ids: if id in movies_id_map: movies_id_map[id][cls.PEOPLE_KEY].append(person) return list(movies_id_map.values())
class TbxFile(SamFile): """ TBX File Class to parse tbx files Args: file (str): file location can be local (full path) or hosted publicly columns ([str]) : column names for various columns in file Attributes: file: a pysam file object fileSrc: location of the file cacheData: cache of accessed data in memory columns: column names to use """ def __init__(self, file, columns=[ "chr", "start", "end", "width", "strand", "geneid", "exon_starts", "exon_ends", "gene" ]): self.file = pysam.TabixFile(file) self.cacheData = {} self.columns = columns # iter = pysam.tabix_iterator(open(file), parser = pysam.asTuple) # (result, _) = get_range_helper(self.toDF, self.get_bin, self.get_col_names, None, None, None, iter, self.columns, respType="DataFrame") # for x, r in enumerate(self.iterator(open(file), pysam.asTuple)): # print(x) # print(r) # print("Parsing chromsomes and their lengths") # chromosomes = [] # groupByChr = result.groupby("chr") # for name, gdf in groupByChr: # chromosomes.append([name, 1, int(gdf["end"].values.max())]) # self.chromosomes = chromosomes def get_bin(self, x): # return (chr) + tuple(x.split('\t')) return tuple(x.split('\t')) def get_col_names(self, result): if self.columns is None: colLength = len(result) self.columns = ["chr", "start", "end"] for i in range(colLength - 3): self.columns.append("column" + str(i)) return self.columns def toDF(self, result): return toDataFrame(result, self.columns) def getRange(self, chr, start, end, bins=2000, zoomlvl=-1, metric="AVG", respType="DataFrame"): """Get data for a given genomic location Args: chr (str): chromosome start (int): genomic start end (int): genomic end respType (str): result format type, default is "DataFrame Returns: result a DataFrame with matched regions from the input genomic location if respType is DataFrame else result is an array error if there was any error during the process """ try: iter = self.file.fetch(chr, start, end) # result = [] # for x in iter: # cols = (chr) + tuple(x.split('\t')) # result.append(cols) # if self.columns is None: # colLength = len(result[0]) # self.columns = ["chr", "start", "end"] # for i in colLength: # self.columns.append("column" + str(i)) # if respType is "DataFrame": # result = toDataFrame(result, self.columns) (result, _) = get_range_helper(self.toDF, self.get_bin, self.get_col_names, chr, start, end, iter, self.columns, respType) return result, None except ValueError as e: raise Exception("didn't find chromId with the given name") @cached(ttl=None, cache=Cache.MEMORY, serializer=PickleSerializer(), namespace="tbxsearchgene") async def searchGene(self, query, maxResults=5): return [], None @cached(ttl=None, cache=Cache.MEMORY, serializer=PickleSerializer(), namespace="tbxgetdata") async def get_data(self, chr, start, end, bins=2000, zoomlvl=-1, metric="AVG", respType="DataFrame"): return self.getRange(chr, start, end, bins=bins, zoomlvl=zoomlvl, metric=metric, respType=respType)
class Bot(BaseBot): """ 飞书 协议 Bot 适配。继承属性参考 `BaseBot <./#class-basebot>`_ 。 """ @property def type(self) -> str: return "feishu" @property def api_root(self) -> str: if self.feishu_config.is_lark: return "https://open.larksuite.com/open-apis/" else: return "https://open.feishu.cn/open-apis/" @classmethod def register(cls, driver: Driver, config: "Config"): super().register(driver, config) cls.feishu_config = FeishuConfig(**config.dict()) @classmethod @overrides(BaseBot) async def check_permission( cls, driver: Driver, request: HTTPRequest ) -> Tuple[Optional[str], Optional[HTTPResponse]]: if not isinstance(request, HTTPRequest): log("WARNING", "Unsupported connection type, available type: `http`") return None, HTTPResponse( 405, b"Unsupported connection type, available type: `http`") encrypt_key = cls.feishu_config.encrypt_key if encrypt_key: encrypted = json.loads(request.body)["encrypt"] decrypted = AESCipher(encrypt_key).decrypt_string(encrypted) data = json.loads(decrypted) else: data = json.loads(request.body) challenge = data.get("challenge") if challenge: return data.get("token"), HTTPResponse( 200, json.dumps({ "challenge": challenge }).encode()) schema = data.get("schema") if not schema: return None, HTTPResponse( 400, b"Missing `schema` in POST body, only accept event of version 2.0" ) headers = data.get("header") if headers: token = headers.get("token") app_id = headers.get("app_id") else: log("WARNING", "Missing `header` in POST body") return None, HTTPResponse(400, b"Missing `header` in POST body") if not token: log("WARNING", "Missing `verification token` in POST body") return None, HTTPResponse( 400, b"Missing `verification token` in POST body") else: if token != cls.feishu_config.verification_token: log("WARNING", "Verification token check failed") return None, HTTPResponse(403, b"Verification token check failed") return app_id, HTTPResponse(200, b'') async def handle_message(self, message: bytes): """ :说明: 处理事件并转换为 `Event <#class-event>`_ """ data: dict = json.loads(message) if data.get("type") == "url_verification": return try: header = data["header"] event_type = header["event_type"] if data.get("event"): if data["event"].get("message"): event_type += f".{data['event']['message']['chat_type']}" models = get_event_model(event_type) for model in models: try: event = model.parse_obj(data) break except Exception as e: log("DEBUG", "Event Parser Error", e) else: event = Event.parse_obj(data) _check_at_me(self, event) _check_nickname(self, event) await handle_event(self, event) except Exception as e: logger.opt(colors=True, exception=e).error( f"<r><bg #f8bbd0>Failed to handle event. Raw: {escape_tag(str(data))}</bg #f8bbd0></r>" ) def _construct_url(self, path: str) -> str: return self.api_root + path @cached(ttl=60 * 60, cache=Cache.MEMORY, key="_feishu_tenant_access_token", serializer=PickleSerializer()) async def _fetch_tenant_access_token(self) -> str: try: async with httpx.AsyncClient() as client: response = await client.post(self._construct_url( "auth/v3/tenant_access_token/internal/"), json={ "app_id": self.feishu_config.app_id, "app_secret": self.feishu_config.app_secret }, timeout=self.config.api_timeout) if 200 <= response.status_code < 300: result = response.json() return result["tenant_access_token"] else: raise NetworkError(f"HTTP request received unexpected " f"status code: {response.status_code}") except httpx.InvalidURL: raise NetworkError("API root url invalid") except httpx.HTTPError: raise NetworkError("HTTP request failed") @overrides(BaseBot) async def _call_api(self, api: str, **data) -> Any: log("DEBUG", f"Calling API <y>{api}</y>") if isinstance(self.request, HTTPRequest): if not self.api_root: raise ApiNotAvailable headers = {} self.feishu_config.tenant_access_token = await self._fetch_tenant_access_token( ) headers[ "Authorization"] = "Bearer " + self.feishu_config.tenant_access_token try: async with httpx.AsyncClient( timeout=self.config.api_timeout) as client: response = await client.send( httpx.Request(data["method"], self.api_root + api, json=data.get("body", {}), params=data.get("query", {}), headers=headers)) if 200 <= response.status_code < 300: if response.headers["content-type"].startswith( "application/json"): result = response.json() else: result = response.content return _handle_api_result(result) raise NetworkError(f"HTTP request received unexpected " f"status code: {response.status_code} " f"response body: {response.text}") except httpx.InvalidURL: raise NetworkError("API root url invalid") except httpx.HTTPError: raise NetworkError("HTTP request failed") @overrides(BaseBot) async def call_api(self, api: str, **data) -> Any: """ :说明: 调用 飞书 协议 API :参数: * ``api: str``: API 名称 * ``**data: Any``: API 参数 :返回: - ``Any``: API 调用返回数据 :异常: - ``NetworkError``: 网络错误 - ``ActionFailed``: API 调用失败 """ return await super().call_api(api, **data) @overrides(BaseBot) async def send(self, event: Event, message: Union[str, Message, MessageSegment], at_sender: bool = False, **kwargs) -> Any: msg = message if isinstance(message, Message) else Message(message) if isinstance(event, GroupMessageEvent): receive_id, receive_id_type = event.event.message.chat_id, "chat_id" elif isinstance(event, PrivateMessageEvent): receive_id, receive_id_type = event.get_user_id(), "open_id" else: raise ValueError( "Cannot guess `receive_id` and `receive_id_type` to reply!") at_sender = at_sender and bool(event.get_user_id()) if at_sender and receive_id_type == "chat_id": msg = MessageSegment.at(event.get_user_id()) + " " + msg msg_type, content = MessageSerializer(msg).serialize() params = { "method": "POST", "query": { "receive_id_type": receive_id_type }, "body": { "receive_id": receive_id, "content": content, "msg_type": msg_type } } return await self.call_api(f"im/v1/messages", **params)
import aiohttp import async_timeout from bs4 import BeautifulSoup from aiocache.serializers import PickleSerializer, JsonSerializer from urllib.parse import urlparse, parse_qs, urljoin from novel.database.mongodb import MotorBase from novel.fetcher.decorators import cached from novel.fetcher.function import target_fetch, get_time, get_html_by_requests, get_random_user_agent from novel.fetcher.extract_novels import extract_pre_next_chapter from novel.config import RULES, LATEST_RULES, LOGGER @cached(ttl=300, key_from_attr='url', serializer=PickleSerializer(), namespace="main") async def cache_novels_content(url, netloc): headers = { 'user-agent': await get_random_user_agent() } html = await target_fetch(headers=headers, url=url) if not html: html = get_html_by_requests(url=url, headers=headers) if html: soup = BeautifulSoup(html, 'html5lib') selector = RULES[netloc].content_selector if selector.get('id', None): content = soup.find_all(id=selector['id']) elif selector.get('class', None): content = soup.find_all(class_=selector['class']) else:
:param artist_name: artist's name :return: (Song) a Song instance """ listen(db.engine, 'connect', load_unicode_extension) song_in_database = db.session.query(Song). \ join(Artist).filter(Artist.name.like(artist_name)). \ filter(Song.title.like(track_title)).first() if not song_in_database: print( f"COULD NOT find: Track({track_title}) by Artist({artist_name}) in database" ) return None return song_in_database @cached(ttl=3600, serializer=PickleSerializer(), cache=Cache.MEMORY) async def get_track_info_shortcut(track_title: str, artist_name: str, spotify_tekore_client): """ a shortcut function that combines two methods of finding track info: database and spotify used for finding track info in lastfm user's top tracks :param track_title: track's title :param artist_name: artist's name :param spotify_tekore_client: an async spotify API client :return: a dict with all the track's info """ if not track_title or not artist_name: return None track = find_track_in_database(track_title, artist_name) if not track: track = await fetch_spotify_track_info(track_title, artist_name,
def test_init(self): serializer = PickleSerializer() assert isinstance(serializer, BaseSerializer) assert serializer.DEFAULT_ENCODING is None assert serializer.encoding is None
import asyncio from collections import namedtuple from aiocache import RedisCache from aiocache.serializers import PickleSerializer MyObject = namedtuple("MyObject", ["x", "y"]) cache = RedisCache(serializer=PickleSerializer(), namespace="main") async def complex_object(): obj = MyObject(x=1, y=2) await cache.set("key", obj) my_object = await cache.get("key") assert my_object.x == 1 assert my_object.y == 2 def test_python_object(): loop = asyncio.get_event_loop() loop.run_until_complete(complex_object()) loop.run_until_complete(cache.delete("key")) loop.run_until_complete(cache.close()) if __name__ == "__main__": test_python_object()
def test_set_types(self, obj): serializer = PickleSerializer() assert serializer.loads(serializer.dumps(obj)) == obj
def test_loads_with_none(self): assert PickleSerializer().loads(None) is None
def test_loads(self): assert PickleSerializer().loads( b'\x80\x03X\x02\x00\x00\x00hiq\x00.') == "hi"
def test_dumps_with_none(self): assert isinstance(PickleSerializer().dumps(None), bytes)
async def test_add_get_types(self, cache, obj): cache.serializer = PickleSerializer() assert await cache.add(pytest.KEY, obj) is True assert await cache.get(pytest.KEY) == pickle.loads(pickle.dumps(obj))
m = file.File(f[1], f[0]) await db.upsert(m) bar.update(1) current += 1 current_percentage = int(current / total * 100) if current_percentage > percentage: percentage = current_percentage await ws.send(str(percentage)) except asyncpg.exceptions.CheckViolationError as e: warning("Violation: {}".format(e)) await db.refresh() @collection.get('/stats') @helpers.basicauth @cached(cache=SimpleMemoryCache, serializer=PickleSerializer(), key='stats') async def stats(request): '''Music library statistics''' mf = await helpers.get_filter(request) stats = await db.stats(mf) return await helpers.template('stats.html', stats=stats, mf=mf) @collection.route('/generate') @helpers.basicauth async def generate(request): '''Generate a playlist step by step''' # precedent = request.form mf = await helpers.get_filter(request) if request.args.get('play', False): musics = await db.musics(mf)
async def test_multi_set_multi_get_types(self, cache, obj): cache.serializer = PickleSerializer() assert await cache.multi_set([(pytest.KEY, obj)]) is True assert await cache.multi_get([pytest.KEY] ) == [pickle.loads(pickle.dumps(obj))]
class Fun( Games, description=_( "A large set of entertainment commands. Everything from 8ball and D&D roll to " "cat and dog pictures."), colour=discord.Colour.dark_gold(), ): def __init__(self, sonata: core.Sonata): self.sonata = sonata super().__init__() @cached( ttl=60 * 60 * 24, serializer=PickleSerializer(), key_builder=lambda f, s, h: f"{f.__name__}_{h}", ) async def measure_love(self, *args): return random.randint(1, 100) def random_magic_ball_response(self) -> str: responses = [ _("definitely."), _("yes."), _("no."), _("of course."), _("not really."), _("do not be this."), _("99% that no."), _("no, no, and again no (that's for sure)."), _("yes, but later."), _("may be."), _("in no case."), _("who knows?"), _("definitely yes."), _("are you kidding? ") + str(self.sonata.emoji("kekw")), _("I'm tired."), _("I have a headache, ask better tomorrow."), _("I do not know."), _("no, probably."), _("stars say yes."), _("yes! (no) ") + str(self.sonata.emoji("Kappa")), _("what else can you tell?"), _("I dont have time for this."), _("concentrate and ask again."), _("whatever."), _("I should know that!?"), _("no longer makes sense."), _("I won’t even answer."), _("yes, congratulations!"), _("you should not know it."), ] return random.choice(responses) @core.command(aliases=["8ball", "q"], examples=[_("donate to the developer?")]) async def question(self, ctx: core.Context): _("""Answers the question""") await ctx.send( f"{ctx.author.mention}, {self.random_magic_ball_response()}") @core.command() async def coin(self, ctx: core.Context): _("""Throws a coin""") sides = [_("eagle"), _("tails")] await ctx.send(f"{ctx.author.mention}, {random.choice(sides)} " + str(self.sonata.emoji("coin"))) @core.command(examples=[_("coffee tea juice"), _('love "doesn\'t love"')]) async def choose(self, ctx: core.Context, *options: commands.clean_content()): _("""Selects one of the options""") if not options: return await ctx.inform(_("I have nothing to choose from")) choice = random.choice(options) await ctx.send(f"{ctx.author.mention}, {choice.strip()}") @core.command( aliases=["dice"], usage="[x][dy][+z] [+ [x][dy][+z]]...", examples=["5", "d54", "2d8", "+10 + 2d10"], ) async def roll(self, ctx: core.Context, *, expression: str = ""): _("""Rolls the dice Template: 1d6+0 Classic dice from D&D. The most common designation that came to D&D is \ `(x)d(y)+(z)` (sometimes "translated" as `(x)to(y)+(z)`). `Throwing \ (x)d(y)+(z)` means that you need to throw (x) times a dice with (y) edges, \ add the results and add (z). If any of the numbers is not specified, the \ default value from the template will be used. For example, `3d6` means the sum \ of the values drawn on three hexagonal cubes, and `2d10+5` - on two \ decahedrons, plus five. You can also throw several combinations at once and get \ the total result. To do this, split the combinations with " + " (plus with \ spaces).""") exps = expression.split(" + ") result = 0 for exp in exps: match = re.match( r"^(?P<count>[1-9]\d*)?(?:d(?P<size>[1-9]\d*))?(?:\+(?P<offset>\d*))?$", exp, ) if match is None: await ctx.send(_("Invalid expression format.")) return count, size, offset = match.groups() count = 1 if count is None else int(count) size = 6 if size is None else int(size) offset = 0 if offset is None else int(offset) if count > 100000: count = 100000 if size > 100000: size = 100000 if offset > 100000: offset = 100000 while count > 0: result += random.randint(1, size) count -= 1 result += offset await ctx.send(f"{ctx.author.mention}, {result}") @core.command() async def cat(self, ctx: core.Context): _("""Finds a random cat image""") async with ctx.session.get( "https://api.thecatapi.com/v1/images/search", headers={"x-api-key": self.sonata.config["api"].cat_api}, ) as resp: if resp.status != 200: return await ctx.send( _("No cat found ") + self.sonata.emoji("BibleThump")) js = await resp.json() await ctx.send(embed=discord.Embed(colour=self.colour).set_image( url=js[0]["url"])) @core.group(name="боня", hidden=True) @commands.check(lambda ctx: ctx.guild.id in (750688889823297569, 313726240710197250)) async def bonya(self, ctx: core.Context): """Находит случайную фотографю Бони""" if ctx.invoked_subcommand is not None: return cursor = ctx.db.bonya.aggregate([{"$sample": {"size": 1}}]) await cursor.fetch_next doc = cursor.next_object() await ctx.send(doc["url"]) @bonya.command(name="добавить") @commands.check(lambda ctx: ctx.author.id in (616989796887298049, 149722383165423616)) async def bonya_add(self, ctx: core.Context, url: str): """Добавляет новую фотографию Бони""" await ctx.db.bonya.insert_one({"url": url}) await ctx.send("Фото добавлено") @core.command(examples=["akita"]) async def dog(self, ctx: core.Context, breed: to_lower = None): _("""Finds a random dog image You can also specify the breed of the dog. """) dog_api = DogAPI(ctx.session) data = await dog_api.random(breed) if breed and data.get("code") == 404: data = await dog_api.list() message = ", ".join(data.get("message")) return await ctx.inform(f"```{message}```", title=_("Breed list")) embed = discord.Embed(colour=self.colour) embed.set_image(url=data.get("message")) await ctx.send(embed=embed) @core.command(examples=[_("@Member")]) @commands.guild_only() async def choke(self, ctx: core.Context, member: discord.Member): _("""Choke a guild member""") await ctx.send( _("*{author} chokes {target}* ").format( author=ctx.author.display_name, target=member.mention) + str(self.sonata.emoji("choke"))) with suppress(discord.HTTPException): await ctx.message.delete() @core.command(examples=[_("@Member")]) @commands.guild_only() async def hug(self, ctx: core.Context, member: discord.Member): _("""Hug a guild member""") await ctx.send( _("*{author} hugs {target}* ").format( author=ctx.author.display_name, target=member.mention) + str(self.sonata.emoji("GivePLZ"))) with suppress(discord.HTTPException): await ctx.message.delete() @core.command(examples=[_("@Member")]) @commands.guild_only() async def hit(self, ctx: core.Context, member: discord.Member): _("""Hit a guild member""") await ctx.send( _("*{author} hits {target}* ").format( author=ctx.author.display_name, target=member.mention) + str(self.sonata.emoji("peepoSmash"))) with suppress(discord.HTTPException): await ctx.message.delete() @core.command(examples=[_("@Member")]) @commands.guild_only() async def kiss(self, ctx: core.Context, member: discord.Member): _("""Kiss a guild member""") await ctx.send( _("*{author} kisses {target}* ").format( author=ctx.author.display_name, target=member.mention) + "😘") with suppress(discord.HTTPException): await ctx.message.delete() @core.command(examples=[_("@Member")]) @commands.guild_only() async def love(self, ctx: core.Context, *, target: Union[discord.Member, str]): _("Measures love") if isinstance(target, discord.Member) and target.id == ctx.bot.user.id: return await ctx.inform(_("Love you 💗")) _hash = frozenset({hash(ctx.author), hash(target)}) love = await self.measure_love(_hash) await ctx.inform( _("{love}% 💗 between {author} and {target}.").format( love=love, author=ctx.author.mention, target=target.mention if isinstance(target, discord.Member) else target, )) @core.command(examples=[_("reflects on the eternal")]) @commands.guild_only() async def me(self, ctx: core.Context, *, action): _("""Perform a 3rd person action""") await ctx.send(f"*{ctx.author.display_name} {action}*") with suppress(discord.HTTPException): await ctx.message.delete() @core.command(examples=[_("@Member")]) @commands.guild_only() async def wink(self, ctx: core.Context, member: discord.Member): _("""Wink at guild member""") await ctx.send( _("*{author} winks at {target}* ").format( author=ctx.author.display_name, target=member.mention) + str(self.sonata.emoji("peepoWink"))) with suppress(discord.HTTPException): await ctx.message.delete()
def test_dumps_and_loads(self): obj = Dummy(1, 2) serializer = PickleSerializer() assert serializer.loads(serializer.dumps(obj)) == obj
} params = {'ie': 'utf-8', 'src': 'noscript_home', 'shb': 1, 'q': novels_name, } html = await self.fetch_url(client=client, url=url, params=params, headers=headers) if html: soup = BeautifulSoup(html, 'html5lib') result = soup.find_all(class_='res-list') extra_tasks = [self.data_extraction(client=client, html=i) for i in result] tasks = [asyncio.ensure_future(i) for i in extra_tasks] done_list, pending_list = await asyncio.wait(tasks) res = [task.result() for task in done_list if task.result()] return res else: return [] @cached(ttl=259200, key_from_attr='novels_name', serializer=PickleSerializer(), namespace="novels_name") async def start(novels_name): """ Start spider :return: """ return await SoNovels.start(novels_name) if __name__ == '__main__': # Start import aiocache REDIS_DICT = {} aiocache.settings.set_defaults( class_="aiocache.RedisCache",
'title': title, 'url': url.replace('index.html', '').replace('Index.html', ''), 'time': time, 'is_parse': is_parse, 'is_recommend': is_recommend, 'timestamp': timestamp, 'netloc': netloc } except Exception as e: self.logger.exception(e) return None @cached(ttl=259200, key_from_attr='novels_name', serializer=PickleSerializer(), namespace="novels_name") async def start(novels_name): """ Start spider :return: """ return await SoSearchEngine.start(novels_name) if __name__ == '__main__': # Start import aiocache REDIS_DICT = {} aiocache.settings.set_defaults(
def test_dumps(self): assert PickleSerializer().dumps( "hi") == b'\x80\x03X\x02\x00\x00\x00hiq\x00.'