mirror of
https://gitlab.com/2-chainz/2chainz.git
synced 2025-08-05 05:01:27 +00:00
Compare commits
8 Commits
08c4b96918
...
main
Author | SHA1 | Date | |
---|---|---|---|
305ee50cdf | |||
7d1c8a3e64 | |||
1da2d71eeb | |||
fbf10556ee | |||
52dd2fd00f | |||
49d023b229 | |||
130a9354cb | |||
8421d7092f |
11
Dockerfile
11
Dockerfile
@@ -10,17 +10,10 @@ ENV UV_COMPILE_BYTECODE=1
|
|||||||
# Copy from the cache instead of linking since it's a mounted volume
|
# Copy from the cache instead of linking since it's a mounted volume
|
||||||
ENV UV_LINK_MODE=copy
|
ENV UV_LINK_MODE=copy
|
||||||
|
|
||||||
# Copy dependency files
|
|
||||||
COPY uv.lock pyproject.toml ./
|
|
||||||
|
|
||||||
# Install the project's dependencies using the lockfile and settings
|
|
||||||
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
||||||
uv sync --locked --no-install-project --no-dev
|
|
||||||
|
|
||||||
# Then, add the rest of the project source code and install it
|
|
||||||
COPY . /app
|
COPY . /app
|
||||||
|
|
||||||
RUN --mount=type=cache,target=/root/.cache/uv \
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
||||||
uv sync --locked --no-dev
|
uv sync --locked --no-dev
|
||||||
|
|
||||||
CMD ["uv", "run", "fastapi", "run", "src/two_chainz", "--port", "80", "--proxy-headers"]
|
CMD ["uv", "run", "--no-dev", "fastapi", "run", "src/two_chainz", "--port", "80", "--proxy-headers"]
|
||||||
|
|
||||||
|
285
data.toml
285
data.toml
@@ -1,113 +1,183 @@
|
|||||||
quotes = [
|
quotes = [
|
||||||
"My side chick got pregnant by her main dude and i'm offended",
|
"My side chick got pregnant by her main dude and i'm offended",
|
||||||
"I kiss your lady, eat her pussy, then kiss the baby",
|
"I kiss your lady, eat her pussy, then kiss the baby",
|
||||||
"Left hand on that steering wheel, right hand on that pussy!",
|
"Left hand on that steering wheel, right hand on that pussy!",
|
||||||
"For my birthday I threw me a surprise party!",
|
"For my birthday I threw me a surprise party!",
|
||||||
"She got a big booty so I call her big booty",
|
"She got a big booty so I call her big booty",
|
||||||
"My girl got a big purse with a purse in it, and her pussy so clean, I can go to church in it!",
|
"My girl got a big purse with a purse in it, and her pussy so clean, I can go to church in it!",
|
||||||
"Beat the pussy up, I need riot gear",
|
"Beat the pussy up, I need riot gear",
|
||||||
"Gas in a Ziplock, now thats loud and clear",
|
"Gas in a Ziplock, now thats loud and clear",
|
||||||
"My wrist deserve a shout out, 'I'm like what up wrist?'\nMy stove deserve a shout out, 'I'm like what up stove?'",
|
"My wrist deserve a shout out, 'I'm like what up wrist?'\nMy stove deserve a shout out, 'I'm like what up stove?'",
|
||||||
"I'm in the kitchen. Yams errrrrwhere",
|
"I'm in the kitchen. Yams errrrrwhere",
|
||||||
"I encourage everyone to pay attention to the issues that matter to you, from jobs and the economy, to education and our schools, to criminal justice reform. Whatever it is that you care about, make sure you use your voice",
|
"I encourage everyone to pay attention to the issues that matter to you, from jobs and the economy, to education and our schools, to criminal justice reform. Whatever it is that you care about, make sure you use your voice",
|
||||||
"If you a chicken head, go somewhere and lay some eggs",
|
"If you a chicken head, go somewhere and lay some eggs",
|
||||||
"Chain hang to my ding-a-ling, chain hang, chain hang to my ding-a-ling",
|
"Chain hang to my ding-a-ling, chain hang, chain hang to my ding-a-ling",
|
||||||
"I tried to get a tan but I'm black already",
|
"I tried to get a tan but I'm black already",
|
||||||
"Then I put a fat rabbit on a Craftmatic!",
|
"Then I put a fat rabbit on a Craftmatic!",
|
||||||
"Yeah, I love them strippers",
|
"Yeah, I love them strippers",
|
||||||
"If I wasn't rapping I'd be trapping",
|
"If I wasn't rapping I'd be trapping",
|
||||||
"Started from the trap, now I rap",
|
"Started from the trap, now I rap",
|
||||||
"I'm so high I can sing to a chandelier\nMy flow a glass of Ace of Spade and yours a can of beer",
|
"I'm so high I can sing to a chandelier\nMy flow a glass of Ace of Spade and yours a can of beer",
|
||||||
"I look you right in your face, sing to your bitch like I'm Drake!",
|
"I look you right in your face, sing to your bitch like I'm Drake!",
|
||||||
"Ass so big, I told her to look back at it!",
|
"Ass so big, I told her to look back at it!",
|
||||||
"Drunk and high at the same time.\nDrinking champagne on an airplane!",
|
"Drunk and high at the same time.\nDrinking champagne on an airplane!",
|
||||||
"Wood grain, chestnut\nTitty fuck, chest nut",
|
"Wood grain, chestnut\nTitty fuck, chest nut",
|
||||||
"Horsepower, horsepower, all this Polo on, I got horsepower",
|
"Horsepower, horsepower, all this Polo on, I got horsepower",
|
||||||
"If I die, bury me inside the Louis store",
|
"If I die, bury me inside the Louis store",
|
||||||
"GI-VEN-CHY, nigga God Bless you",
|
"GI-VEN-CHY, nigga God Bless you",
|
||||||
"My favorite dish is turkey lasagna\nEven my pajamas designer",
|
"My favorite dish is turkey lasagna\nEven my pajamas designer",
|
||||||
"Walked in, ill nigga alert! ill nigga alert!",
|
"Like fuck your baby daddy, his daddy should've worn a condom",
|
||||||
"Like fuck your baby daddy, his daddy should've worn a condom",
|
"I'm the type of nigga thats built to last.\nYou fuck with me, Ill put my foot in your ass",
|
||||||
"I'm the type of nigga thats built to last.\nYou fuck with me, Ill put my foot in your ass",
|
"I wish a nigga would like a kitchen cabinet",
|
||||||
"I wish a nigga would like a kitchen cabinet",
|
"Louie V is my kryptonite",
|
||||||
"Louie V is my kryptonite",
|
"If you woke up this morning, Nigga you winnin!",
|
||||||
"If you woke up this morning, Nigga you winnin!",
|
"I use good pussy like its lotion",
|
||||||
"I use good pussy like its lotion",
|
"Big shit like a dinosaur did it",
|
||||||
"Big shit like a dinosaur did it",
|
"#making bands, yes I am",
|
||||||
"#making bands, yes I am",
|
"I wear versace like its nike, you don't like it do you?",
|
||||||
"I wear versace like its nike, you don't like it do you?",
|
"I bet you feel this bank roll if I bump into you",
|
||||||
"I bet you feel this bank roll if I bump into you",
|
"Sprinter van on me, I got them xans on me,\nDriveway so damn long by the time I leave I'm damn asleep",
|
||||||
"Like fuck your baby daddy, his daddy should've wore a condom",
|
"Bitches round my pool, I made them hoes look like my landscape",
|
||||||
"Sprinter van on me, I got them xans on me,\nDriveway so damn long by the time I leave I'm damn asleep",
|
"Everything Proper, no propaganda",
|
||||||
"Bitches round my pool, I made them hoes look like my landscape",
|
"Big sack, a lotta hoes like Santa",
|
||||||
"Everything Proper, no propaganda",
|
"Attitude on some 'Fuck you too!'\nBankroll on 'What it do, boo?'",
|
||||||
"Big sack, a lotta hoes like Santa",
|
"I got a pocket full of money, it got me walking all slew-foot",
|
||||||
"Attitude on some 'Fuck you too!'\nBankroll on 'What it do, boo?'",
|
"I'm on my wave like a cruise ship",
|
||||||
"I got a pocket full of money, it got me walking all slew-foot",
|
"In that hoe mouth like a toothpick",
|
||||||
"I'm on my wave like a cruise ship",
|
"My new bitch gon' pull me a new bitch,\nThen pull me a new bitch\nSee that is a snowball effect",
|
||||||
"In that hoe mouth like a toothpick",
|
"I got a mansion full of marble floors,\nIt look like I could go bowl in this bitch",
|
||||||
"My new bitch gon' pull me a new bitch,\nThen pull me a new bitch\nSee that is a snowball effect",
|
"I got a big amount, I took a different route,\nI am the pick of the litter",
|
||||||
"I got a mansion full of marble floors,\nIt look like I could go bowl in this bitch",
|
"Everywhere I go, the rod with me,\n'Cause these niggas actin' too fishy",
|
||||||
"I got a big amount, I took a different route,\nI am the pick of the litter",
|
"Put codeine in a Snapple,\nPut codeine on a salad,\nGuess I'm on a codeine diet!",
|
||||||
"Everywhere I go, the rod with me,\n'Cause these niggas actin' too fishy",
|
"I love bad bitches, that's my fuckin' problem",
|
||||||
"Put codeine in a Snapple,\nPut codeine on a salad,\nGuess I'm on a codeine diet!",
|
"Hundred bands, cut your girl\nNow your girl need a Band-Aid",
|
||||||
"I love bad bitches, that's my fuckin' problem",
|
"Money tall like Jordan",
|
||||||
"Hundred bands, cut your girl\nNow your girl need a Band-Aid",
|
'She said she love me, I said, "Baby girl, fall in line"',
|
||||||
"Money tall like Jordan",
|
'Walked in, "Ill nigga alert! Ill nigga alert!"',
|
||||||
'She said she love me, I said, "Baby girl, fall in line"',
|
"If having a bad bitch was a crime, I'd be arrested!",
|
||||||
'Walked in, "Ill nigga alert! Ill nigga alert!"',
|
"Truuuuu",
|
||||||
"If having a bad bitch was a crime, I'd be arrested!",
|
"Got a pocket full of money and a mind full of ideas!",
|
||||||
"Truuuuu",
|
"Inside of the Mayback look like it came out of IKEA",
|
||||||
"Got a pocket full of money and a mind full of ideas!",
|
"Bought my boo bigger tits and a bigger ass!",
|
||||||
"Inside of the Mayback look like it came out of IKEA",
|
"I smoke strong; that Popeye",
|
||||||
"Bought my boo bigger tits and a bigger ass!",
|
"Name a nigga that want some, I'll out-rap his ass, out-trap his ass, Put his ass in a plastic bag with his trashy ass!",
|
||||||
"I smoke strong; that Popeye",
|
"Financial outbreak, I'm free but I ain't out yet",
|
||||||
"Name a nigga that want some, I'll out-rap his ass, out-trap his ass, Put his ass in a plastic bag with his trashy ass!",
|
"Ridin with the plug so I'm close to the outlet",
|
||||||
"Financial outbreak, I'm free but I ain't out yet",
|
"Okay now Nicki, Nicki, Nicki, put it in your kidney",
|
||||||
"Ridin with the plug so I'm close to the outlet",
|
"Done got rich, don't give no shit",
|
||||||
"Okay now Nicki, Nicki, Nicki, put it in your kidney",
|
"Old enough to be your Daddy, young enough to fuck your Mama",
|
||||||
"Done got rich, don't give no shit",
|
"Young enough to fuck your sister, young enough to fuck your auntie",
|
||||||
"Old enough to be your Daddy, young enough to fuck your Mama",
|
"I ain't messing with your Grannie, I just juuged her out them Xannies",
|
||||||
"Young enough to fuck your sister, young enough to fuck your auntie",
|
"Niggas claimed they got a tool but never used the hammer",
|
||||||
"I ain't messing with your Grannie, I just juuged her out them Xannies",
|
"Old enough to son you niggas, young enough to fuck your ex",
|
||||||
"Niggas claimed they got a tool but never used the hammer",
|
"A tall nigga in the coupe, so I'm easy to find",
|
||||||
"Old enough to son you niggas, young enough to fuck your ex",
|
"She want Versace so I flew her out straight to Milan",
|
||||||
"A tall nigga in the coupe, so I'm easy to find",
|
"I turn your curly hair into that bone straightener",
|
||||||
"She want Versace so I flew her out straight to Milan",
|
"She say I killed the pussy, I seen the affidavit",
|
||||||
"I turn your curly hair into that bone straightener",
|
"My house so far back in the woods, that can't nobody find us,\nA driveway so long that you can run out of gas",
|
||||||
"She say I killed the pussy, I seen the affidavit",
|
"And my shawty gonna ride me like a Peloton",
|
||||||
"My house so far back in the woods, that can't nobody find us,\nA driveway so long that you can run out of gas",
|
"I stay fly, yes I'm fly, land on Mike Pence",
|
||||||
"And my shawty gonna ride me like a Peloton",
|
"This a yacht and that's a long way from a slaveship",
|
||||||
"I stay fly, yes I'm fly, land on Mike Pence",
|
"She been late night snackin', but shawty still my baby",
|
||||||
"This a yacht and that's a long way from a slaveship",
|
"I'm from where a nut'll cost you eighty bucks (Southside)",
|
||||||
"She been late night snackin', but shawty still my baby",
|
"She been quarantine, now lil' shawty thick",
|
||||||
"I'm from where a nut'll cost you eighty bucks (Southside)",
|
"Walk in the club make a typhoon",
|
||||||
"She been quarantine, now lil' shawty thick",
|
"Dope came with a lighter",
|
||||||
"Walk in the club make a typhoon",
|
"Got a million dollars in my memory bank",
|
||||||
"Dope came with a lighter",
|
"Toni used to buy the lean by the fuckin' keg",
|
||||||
"Got a million dollars in my memory bank",
|
"Toni starin' at her, I think Toni want that bitch",
|
||||||
"Toni used to buy the lean by the fuckin' keg",
|
"I act a donkey, they just don't know where to pin the tail",
|
||||||
"Toni starin' at her, I think Toni want that bitch",
|
"I put slapping pussy niggas on my checklist",
|
||||||
"I act a donkey, they just don't know where to pin the tail",
|
"Can't walk a day in these shoes, these don't come in your size",
|
||||||
"I put slapping pussy niggas on my checklist",
|
"You always posting cars and never post your home décor",
|
||||||
"Can't walk a day in these shoes, these don't come in your size",
|
"I got a scale and a Ziploc, may I take your order?",
|
||||||
"You always posting cars and never post your home décor",
|
"Before the pandemic, still wouldn't fuck with Corona",
|
||||||
"I got a scale and a Ziploc, may I take your order?",
|
"Pay for a funeral, find out he snitched, want a refund",
|
||||||
"Before the pandemic, still wouldn't fuck with Corona",
|
"My best friend when I was trappin' was the mobile phone",
|
||||||
"Pay for a funeral, find out he snitched, want a refund",
|
"Never been a Yes Man, so I don't feel like I have to explain",
|
||||||
"My best friend when I was trappin' was the mobile phone",
|
"Use a diamond chain for a tie, had a connect before Wi-Fi",
|
||||||
"Never been a Yes Man, so I don't feel like I have to explain",
|
"If you ain't first, you last place",
|
||||||
"Use a diamond chain for a tie, had a connect before Wi-Fi",
|
"If rap don't work, I'll buy a stove\nIf rap don't work, I'll buy a scale",
|
||||||
"If you ain't first, you last place",
|
"I'm at Esco, double park in front of the firehouse and I'm fire as hell",
|
||||||
"If rap don't work, I'll buy a stove\nIf rap don't work, I'll buy a scale",
|
"F y'all niggas, ex-drug dealer, ex-ball player, X Games\nGoin' down like Aspen, diamonds in the watch like Aspirin",
|
||||||
"I'm at Esco, double park in front of the firehouse and I'm fire as hell",
|
"I had that pussy pissin once I hit that Kidney",
|
||||||
"F y'all niggas, ex-drug dealer, ex-ball player, X Games\nGoin' down like Aspen, diamonds in the watch like Aspirin",
|
"Told my lawyer, \"Imma call you back, this my other lawyer\"",
|
||||||
"I had that pussy pissin once I hit that Kidney",
|
"if you was a computer, you would be a Microsoft",
|
||||||
|
"you don't brush, thats the only way you gon' get some plaques today",
|
||||||
|
"call me Dos Cadenas, por favor",
|
||||||
|
"I be eatin shrim and crab legs every day",
|
||||||
|
"Yesterday when I woke up, I ate lobster",
|
||||||
|
"she said she wanna drink my kids, foster",
|
||||||
|
"I'm indulgin' cause money the motivator",
|
||||||
|
"Its a good day to get some paper",
|
||||||
|
"I'm a digi-scale user, and you just a user",
|
||||||
|
"Tighter than a thong, you're assed out",
|
||||||
|
"Me and my wife sip wine somewhere you can't find",
|
||||||
|
"I smell like Porsche and Benihanas",
|
||||||
|
"I don't gatekeep, I want everyone to eat",
|
||||||
|
"Expired tag, I ride with a lawyer",
|
||||||
|
"After the performance, I hopped in a foreign",
|
||||||
|
"mind full of greed - Pellegrino, lemon squeeze",
|
||||||
|
"lookin at a chandelier during a wine tasting",
|
||||||
|
"Louis bag, Prada bag, body bag, kinda sad",
|
||||||
|
"rapping my therapy",
|
||||||
|
"eat mushrooms like they jellybeans",
|
||||||
|
"Mindin' my business, drinkin' water, doin' crunches",
|
||||||
|
"Getting paid for discussions over Alchemist production",
|
||||||
|
"wear a Rollie when I'm fuckin'",
|
||||||
|
"You need to put a condom on cause you may not be that lucky",
|
||||||
|
"drinkin codeine in my Phantom",
|
||||||
|
"came with three hoes like I'm Santa",
|
||||||
|
"Hustle plus passion equals success",
|
||||||
|
"Sellin seasoning to Martha Stewart",
|
||||||
|
"This track ought to wake'em up, call it Folgers",
|
||||||
|
"Me llama Dos Cadenas, baby, buenas noches",
|
||||||
|
"Yeah I like it when its tight but imma make it looser",
|
||||||
|
"Got a gold toilet bowl to take a number deuce",
|
||||||
|
"I gave her the D, like she was tryin to play some offense",
|
||||||
|
"told him fly us Precheck",
|
||||||
|
"Before we hit the driveway, got my hand on her thighs",
|
||||||
|
"concrete jungle, I'll fuck Jane though",
|
||||||
|
"We on different planes if we is in the same boat",
|
||||||
|
"She so thick, its kinda hard to say skinny dip",
|
||||||
|
"I'm cuffin, put the pussy on probation",
|
||||||
|
"Rivalry appear, cauliflower his ear",
|
||||||
|
"Pull a rabbit out the hat with the magic stick",
|
||||||
|
"Checkerboard luggage, ramen in the cupboard",
|
||||||
|
"Vocals warmed up, beyond Ford tough",
|
||||||
|
"You know, you deserve the Pretty Pussy Award",
|
||||||
|
"Sound like I'm stirrin' mac and cheese in your lap",
|
||||||
|
"I got blinds in my whip like a condo",
|
||||||
|
"Whats a gorilla to Godzilla?",
|
||||||
|
"I don't compete, but you can't compete",
|
||||||
|
"we on a date, make it rain some ones",
|
||||||
|
"I keep it rollin like paraplegic",
|
||||||
|
"I did the math, ain't no way we equal",
|
||||||
|
"This is chess not checkers, like an A-cup",
|
||||||
|
"Two BBLs, you know she extra",
|
||||||
|
"In the kitchen, scale, fork, and pistol",
|
||||||
|
"I done fell in love with a thicc bitch",
|
||||||
|
"You know I been trappin since the dial-up",
|
||||||
|
"I am so cold, it look like Freon attack",
|
||||||
|
"this a Cullinan, bitch, not a Range Rover",
|
||||||
|
"I'm the real thing, you a carbon copy",
|
||||||
|
"I got my hands on her ass like a motorcycle",
|
||||||
|
"I like pussy, she like pussy, we just like twins",
|
||||||
|
"FN with hollow tips, I ain't with the politics",
|
||||||
|
"If you don't see me shining you need an optometrist",
|
||||||
|
"Always with the dog, like I'm Charlie Brown",
|
||||||
|
"Tony Alimony - married to the streets",
|
||||||
|
"My favorite plastic bag got some drugs in it",
|
||||||
|
"I wish Nobu had a drive-thru",
|
||||||
|
"I bet the neighbors know my name, they call me \"Oh fuck, oh shit\"",
|
||||||
|
"I'm rich and ratchet",
|
||||||
|
"First rapper with a Versace deal, did a chain reaction",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
aliases = [
|
aliases = [
|
||||||
{ name = "2 Chainz", weight = 50 },
|
{ name = "2 Chainz", weight = 50 },
|
||||||
|
{ name = "2 Chainzzzzz", weight = 50 },
|
||||||
{ name = "Tity Boi", weight = 10 },
|
{ name = "Tity Boi", weight = 10 },
|
||||||
{ name = "Daniel Son; Necklace Don", weight = 10 },
|
{ name = "Daniel Son; Necklace Don", weight = 10 },
|
||||||
{ name = "Drenchgod", weight = 5 },
|
{ name = "Drenchgod", weight = 5 },
|
||||||
@@ -120,10 +190,15 @@ aliases = [
|
|||||||
{ name = "JEFE", weight = 5 },
|
{ name = "JEFE", weight = 5 },
|
||||||
{ name = "TONI", weight = 25 },
|
{ name = "TONI", weight = 25 },
|
||||||
{ name = "BIG TONI", weight = 10 },
|
{ name = "BIG TONI", weight = 10 },
|
||||||
{ name = "PRETTI TONI", weight = 1 },
|
{ name = "PRETTI TONI", weight = 10 },
|
||||||
{ name = "TONÉ", weight = 1 },
|
{ name = "TONÉ", weight = 1 },
|
||||||
{ name = "2 TONE TONI", weight = 5 },
|
{ name = "2 TONE TONI", weight = 5 },
|
||||||
{ name = "TONI 2-STIX", weight = 1 },
|
{ name = "TONI 2-STIX", weight = 1 },
|
||||||
{ name = "TONI KEYS", weight = 1 },
|
{ name = "TONI KEYS", weight = 1 },
|
||||||
{ name = "FAT TONI", weight = 10 },
|
{ name = "FAT TONI", weight = 10 },
|
||||||
|
{ name = "Colossal", weight = 1 },
|
||||||
|
{ name = "Cane Corso", weight = 1 },
|
||||||
|
{ name = "Escobar Owner", weight = 15 },
|
||||||
|
{ name = "Toni", weight = 10 },
|
||||||
|
{ name = "Deuce", weight = 10 },
|
||||||
]
|
]
|
||||||
|
@@ -18,4 +18,8 @@ build-backend = "hatchling.build"
|
|||||||
packages = ["src/two_chainz"]
|
packages = ["src/two_chainz"]
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
dev = ["httpx>=0.28.1", "pytest>=8.3.5", "ruff>=0.11.11"]
|
dev = [
|
||||||
|
"nltk>=3.9.1",
|
||||||
|
"pytest>=8.3.5",
|
||||||
|
"ruff>=0.11.11",
|
||||||
|
]
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
from itertools import combinations
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
|
from nltk.metrics.distance import edit_distance
|
||||||
|
|
||||||
import two_chainz
|
import two_chainz
|
||||||
from two_chainz import app
|
from two_chainz import app
|
||||||
@@ -28,8 +30,8 @@ class TestApi:
|
|||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"mocked_time,start_time,expected",
|
"mocked_time,start_time,expected",
|
||||||
[
|
[
|
||||||
(100, 50, 50), # 100 - 50 = 50 seconds uptime
|
(100, 50, "50"), # 100 - 50 = 50 seconds uptime
|
||||||
(200, 100, 100), # 200 - 100 = 100 seconds uptime
|
(200, 100, "100"), # 200 - 100 = 100 seconds uptime
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_api_uptime_calculation(self, mocked_time, start_time, expected):
|
def test_api_uptime_calculation(self, mocked_time, start_time, expected):
|
||||||
@@ -68,8 +70,13 @@ class TestData:
|
|||||||
assert two_chainz.data["quotes"]
|
assert two_chainz.data["quotes"]
|
||||||
assert two_chainz.data["aliases"]
|
assert two_chainz.data["aliases"]
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("a, b", combinations(two_chainz.data["quotes"], 2))
|
||||||
|
def test_no_duplicate_quotes(self, a, b):
|
||||||
|
"Use the Levenshtein edit distance since I hand write all the quotes"
|
||||||
|
assert 2 < edit_distance(a, b)
|
||||||
|
|
||||||
@pytest.mark.parametrize("quote", two_chainz.data["quotes"])
|
@pytest.mark.parametrize("quote", two_chainz.data["quotes"])
|
||||||
class TestQuotes:
|
class TestQuote:
|
||||||
def test_no_empty(self, quote):
|
def test_no_empty(self, quote):
|
||||||
assert quote
|
assert quote
|
||||||
|
|
||||||
|
@@ -3,18 +3,19 @@ import time
|
|||||||
import tomllib
|
import tomllib
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import logging
|
|
||||||
from fastapi import FastAPI, Request
|
from fastapi import FastAPI
|
||||||
from fastapi.middleware.trustedhost import TrustedHostMiddleware
|
from fastapi.middleware.trustedhost import TrustedHostMiddleware
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI(
|
||||||
|
title="2 Chainz REST",
|
||||||
|
description="A simple API to get 2 Chainz quotes and aliases. See <a href=https://2chainz.ansonbiggs.com>2chainz.ansonbiggs.com</a> for a full explanation.",
|
||||||
|
)
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
TrustedHostMiddleware,
|
TrustedHostMiddleware,
|
||||||
allowed_hosts=["*"],
|
allowed_hosts=["*"],
|
||||||
)
|
)
|
||||||
logging.basicConfig(level=logging.INFO)
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
|
||||||
@@ -31,37 +32,80 @@ def read_data() -> dict[str, str]:
|
|||||||
data = read_data()
|
data = read_data()
|
||||||
|
|
||||||
|
|
||||||
# Log all requests to debug issues
|
@app.get(
|
||||||
@app.middleware("http")
|
"/api/",
|
||||||
async def log_requests(request: Request, call_next):
|
summary="Health Check",
|
||||||
# Log what's coming in
|
description="Check API health status and uptime",
|
||||||
logger.info(f"Request: {request.method} {request.url.path}")
|
response_description="Health status with timestamp and uptime",
|
||||||
logger.info(f"Host header: {request.headers.get('host')}")
|
tags=["Health"],
|
||||||
logger.info(f"CF-Ray: {request.headers.get('cf-ray', 'Not from Cloudflare')}")
|
responses={
|
||||||
|
200: {
|
||||||
|
"description": "Successful health check",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"example": {
|
||||||
|
"status": "ok",
|
||||||
|
"timestamp": "2025-05-24T10:30:00",
|
||||||
|
"uptime_seconds": "3600.5",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
async def ping() -> dict[str, str]:
|
||||||
|
"""
|
||||||
|
Endpoint to check on the health of the API and to help diagnose issues.
|
||||||
|
|
||||||
try:
|
Returns current status, timestamp, and uptime information.
|
||||||
response = await call_next(request)
|
"""
|
||||||
return response
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Request processing failed: {e}")
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/api/")
|
|
||||||
async def ping():
|
|
||||||
return {
|
return {
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
"timestamp": datetime.now().isoformat(),
|
"timestamp": datetime.now().isoformat(),
|
||||||
"uptime_seconds": round(time.time() - start_time, 2),
|
"uptime_seconds": str(round(time.time() - start_time, 2)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@app.get("/api/quote")
|
@app.get(
|
||||||
|
"/api/quote",
|
||||||
|
summary="2 Chainz Quote",
|
||||||
|
description="Get a quote from 2 Chainz",
|
||||||
|
tags=["Data"],
|
||||||
|
responses={
|
||||||
|
200: {
|
||||||
|
"description": "Successful quote",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"example": {
|
||||||
|
"quote": "Wood grain chestnut, titty fuck chest nut",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
async def quote():
|
async def quote():
|
||||||
return {"quote": random.choice(data["quotes"])}
|
return {"quote": random.choice(data["quotes"])}
|
||||||
|
|
||||||
|
|
||||||
@app.get("/api/alias")
|
@app.get(
|
||||||
|
"/api/alias",
|
||||||
|
summary="2 Chainz Alias",
|
||||||
|
description="Get one of 2 Chainz many aliases",
|
||||||
|
tags=["Data"],
|
||||||
|
responses={
|
||||||
|
200: {
|
||||||
|
"description": "Successful alias",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"example": {
|
||||||
|
"alias": "2 Chainz",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
async def alias():
|
async def alias():
|
||||||
return {"alias": random.choice(data["aliases"])}
|
return {"alias": random.choice(data["aliases"])}
|
||||||
|
|
||||||
|
66
uv.lock
generated
66
uv.lock
generated
@@ -1,4 +1,5 @@
|
|||||||
version = 1
|
version = 1
|
||||||
|
revision = 1
|
||||||
requires-python = ">=3.13"
|
requires-python = ">=3.13"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -11,7 +12,7 @@ dependencies = [
|
|||||||
|
|
||||||
[package.dev-dependencies]
|
[package.dev-dependencies]
|
||||||
dev = [
|
dev = [
|
||||||
{ name = "httpx" },
|
{ name = "nltk" },
|
||||||
{ name = "pytest" },
|
{ name = "pytest" },
|
||||||
{ name = "ruff" },
|
{ name = "ruff" },
|
||||||
]
|
]
|
||||||
@@ -21,7 +22,7 @@ requires-dist = [{ name = "fastapi", extras = ["standard"], specifier = ">=0.115
|
|||||||
|
|
||||||
[package.metadata.requires-dev]
|
[package.metadata.requires-dev]
|
||||||
dev = [
|
dev = [
|
||||||
{ name = "httpx", specifier = ">=0.28.1" },
|
{ name = "nltk", specifier = ">=3.9.1" },
|
||||||
{ name = "pytest", specifier = ">=8.3.5" },
|
{ name = "pytest", specifier = ">=8.3.5" },
|
||||||
{ name = "ruff", specifier = ">=0.11.11" },
|
{ name = "ruff", specifier = ">=0.11.11" },
|
||||||
]
|
]
|
||||||
@@ -62,7 +63,7 @@ name = "click"
|
|||||||
version = "8.2.1"
|
version = "8.2.1"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "colorama", marker = "platform_system == 'Windows'" },
|
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342 }
|
sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342 }
|
||||||
wheels = [
|
wheels = [
|
||||||
@@ -225,6 +226,15 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 },
|
{ url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "joblib"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/dc/fe/0f5a938c54105553436dbff7a61dc4fed4b1b2c98852f8833beaf4d5968f/joblib-1.5.1.tar.gz", hash = "sha256:f4f86e351f39fe3d0d32a9f2c3d8af1ee4cec285aafcb27003dda5205576b444", size = 330475 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7d/4f/1195bbac8e0c2acc5f740661631d8d750dc38d4a32b23ee5df3cde6f4e0d/joblib-1.5.1-py3-none-any.whl", hash = "sha256:4719a31f054c7d766948dcd83e9613686b27114f190f717cec7eaa2084f8a74a", size = 307746 },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "markdown-it-py"
|
name = "markdown-it-py"
|
||||||
version = "3.0.0"
|
version = "3.0.0"
|
||||||
@@ -274,6 +284,21 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 },
|
{ url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nltk"
|
||||||
|
version = "3.9.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "click" },
|
||||||
|
{ name = "joblib" },
|
||||||
|
{ name = "regex" },
|
||||||
|
{ name = "tqdm" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/3c/87/db8be88ad32c2d042420b6fd9ffd4a149f9a0d7f0e86b3f543be2eeeedd2/nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868", size = 2904691 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4d/66/7d9e26593edda06e8cb531874633f7c2372279c3b0f46235539fe546df8b/nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1", size = 1505442 },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "packaging"
|
name = "packaging"
|
||||||
version = "25.0"
|
version = "25.0"
|
||||||
@@ -394,6 +419,29 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 },
|
{ url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "2024.11.6"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/8e/5f/bd69653fbfb76cf8604468d3b4ec4c403197144c7bfe0e6a5fc9e02a07cb/regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519", size = 399494 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/90/73/bcb0e36614601016552fa9344544a3a2ae1809dc1401b100eab02e772e1f/regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84", size = 483525 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0f/3f/f1a082a46b31e25291d830b369b6b0c5576a6f7fb89d3053a354c24b8a83/regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4", size = 288324 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/09/c9/4e68181a4a652fb3ef5099e077faf4fd2a694ea6e0f806a7737aff9e758a/regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0", size = 284617 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fc/fd/37868b75eaf63843165f1d2122ca6cb94bfc0271e4428cf58c0616786dce/regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0", size = 795023 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c4/7c/d4cd9c528502a3dedb5c13c146e7a7a539a3853dc20209c8e75d9ba9d1b2/regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7", size = 833072 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4f/db/46f563a08f969159c5a0f0e722260568425363bea43bb7ae370becb66a67/regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7", size = 823130 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/db/60/1eeca2074f5b87df394fccaa432ae3fc06c9c9bfa97c5051aed70e6e00c2/regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c", size = 796857 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/10/db/ac718a08fcee981554d2f7bb8402f1faa7e868c1345c16ab1ebec54b0d7b/regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3", size = 784006 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c2/41/7da3fe70216cea93144bf12da2b87367590bcf07db97604edeea55dac9ad/regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07", size = 781650 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a7/d5/880921ee4eec393a4752e6ab9f0fe28009435417c3102fc413f3fe81c4e5/regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e", size = 789545 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/dc/96/53770115e507081122beca8899ab7f5ae28ae790bfcc82b5e38976df6a77/regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6", size = 853045 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/31/d3/1372add5251cc2d44b451bd94f43b2ec78e15a6e82bff6a290ef9fd8f00a/regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4", size = 860182 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ed/e3/c446a64984ea9f69982ba1a69d4658d5014bc7a0ea468a07e1a1265db6e2/regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d", size = 787733 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2b/f1/e40c8373e3480e4f29f2692bd21b3e05f296d3afebc7e5dcf21b9756ca1c/regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff", size = 262122 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/45/94/bc295babb3062a731f52621cdc992d123111282e291abaf23faa413443ea/regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a", size = 273545 },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rich"
|
name = "rich"
|
||||||
version = "14.0.0"
|
version = "14.0.0"
|
||||||
@@ -476,6 +524,18 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/8b/0c/9d30a4ebeb6db2b25a841afbb80f6ef9a854fc3b41be131d249a977b4959/starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35", size = 72037 },
|
{ url = "https://files.pythonhosted.org/packages/8b/0c/9d30a4ebeb6db2b25a841afbb80f6ef9a854fc3b41be131d249a977b4959/starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35", size = 72037 },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tqdm"
|
||||||
|
version = "4.67.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540 },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typer"
|
name = "typer"
|
||||||
version = "0.15.3"
|
version = "0.15.3"
|
||||||
|
@@ -40,106 +40,67 @@
|
|||||||
:root {
|
:root {
|
||||||
--color: darkviolet;
|
--color: darkviolet;
|
||||||
--color-bg-secondary: black;
|
--color-bg-secondary: black;
|
||||||
}
|
--color-link: darkviolet;
|
||||||
|
|
||||||
@media screen and (max-width: 400px) {
|
|
||||||
#scroll-icon {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<header style="height: 70vh;">
|
<header style="height: 90vh">
|
||||||
<nav>
|
<nav>
|
||||||
<ul>
|
<a href="https://2chainz.ansonbiggs.com">2chainz.ansonbiggs.com</a>
|
||||||
<li>
|
<p>A REST API for 2 Chainz Quotes</p>
|
||||||
<a href="https://2chainz.ansonbiggs.com">2chainz.ansonbiggs.com</a> - A REST API for 2
|
<a href="https://gitlab.com/2-chainz/2chainz">Source Code</a>
|
||||||
Chainz Quotes
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
</nav>
|
||||||
<section>
|
<section style="height: 50vh">
|
||||||
<blockquote>
|
<blockquote style="margin: auto">
|
||||||
<span id="quote"></span>
|
<span id="quote">TRUUUUUUUU</span>
|
||||||
<footer><i id="alias">- 2 Chainz</i></footer>
|
<footer><i id="alias">- 2 Chainz</i></footer>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</section>
|
</section>
|
||||||
<p>
|
<section>
|
||||||
<a onclick="getQuote()" href="#"
|
<a onclick="getQuote()" href="#"
|
||||||
><b>
|
><b style="width: 20vw">
|
||||||
<ion-icon size="large" name="refresh-circle"></ion-icon><br />
|
<ion-icon size="large" name="refresh-circle"></ion-icon>
|
||||||
New Quote</b
|
<span style="display: grid; place-items: center">New Quote</span>
|
||||||
></a
|
</b>
|
||||||
>
|
</a>
|
||||||
<a id="tweet" href="#"
|
</section>
|
||||||
><b
|
<a href="#scroll" id="scroll-icon" style="padding-top: 10vh"
|
||||||
><ion-icon size="large" name="logo-twitter"></ion-icon> <br />
|
|
||||||
Tweet Quote
|
|
||||||
</b></a
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
<a href="#scroll" id="scroll-icon" style="padding-top: 10vh;"
|
|
||||||
><ion-icon size="large" name="arrow-down-sharp"></ion-icon
|
><ion-icon size="large" name="arrow-down-sharp"></ion-icon
|
||||||
></a>
|
></a>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<hr style="padding-top: 0;" />
|
<hr style="padding-top: 0" />
|
||||||
<header id="scroll">
|
<header id="scroll">
|
||||||
<h2>Usage</h2>
|
<h2>Usage</h2>
|
||||||
|
<p>
|
||||||
|
For exhaustive and up to date documentation see
|
||||||
|
<a href="/docs">/docs</a>
|
||||||
|
</p>
|
||||||
</header>
|
</header>
|
||||||
<details open>
|
<details open>
|
||||||
<summary>Quote</summary>
|
<summary>Quote</summary>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Returns a random 2 Chainz Quote in <code>json</code> format like the
|
Returns a random 2 Chainz Quote in <code>json</code> format like the
|
||||||
following example:
|
following example:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
send a <code>get</code> request to
|
send a <code>get</code> request to
|
||||||
<code
|
<code
|
||||||
><a href="https://chainz.ansonbiggs.com/api/quote"
|
><a href="https://2chainz.ansonbiggs.com/api/quote"
|
||||||
>https://chainz.ansonbiggs.com/api/quote</a
|
>https://2chainz.ansonbiggs.com/api/quote</a
|
||||||
></code
|
></code
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre><code>{
|
<pre><code>{
|
||||||
"quote": "I got a pocket full of money, it got me walking all slew-foot"
|
"quote": "I got a pocket full of money, it got me walking all slew-foot"
|
||||||
}</code></pre>
|
}</code></pre>
|
||||||
|
|
||||||
<details style="margin-left: 5%;">
|
|
||||||
<summary>Parameters</summary>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This endpoint also supports an optional <code>batch</code> parameter
|
|
||||||
to get more than one quote per request. Maximum quotes that the
|
|
||||||
endpoint will return is the amount of quotes in
|
|
||||||
<a
|
|
||||||
href="https://gitlab.com/2-chainz/2-chainz-rest/-/blob/master/quote/quotes.py"
|
|
||||||
>quotes.py</a
|
|
||||||
>
|
|
||||||
and is subject to change. An example return from
|
|
||||||
<code>
|
|
||||||
<a href="https://chainz.ansonbiggs.com/api/quote?batch=2"
|
|
||||||
>https://chainz.ansonbiggs.com/api/quote?batch=2</a
|
|
||||||
></code
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre><code class="json">{
|
|
||||||
"quotes": [
|
|
||||||
"I'm in the kitchen. Yams errrrrwhere.",
|
|
||||||
"Started from the trap, now I rap"
|
|
||||||
]
|
|
||||||
}</code></pre>
|
|
||||||
</details>
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details
|
<details>
|
||||||
><summary>Alias</summary>
|
<summary>Alias</summary>
|
||||||
<p>
|
<p>
|
||||||
Returns a random 2 Chainz alias in <code>json</code> format. The
|
Returns a random 2 Chainz alias in <code>json</code> format. The
|
||||||
return values are weighted and a full list can be seen in
|
return values are weighted and a full list can be seen in
|
||||||
@@ -151,20 +112,21 @@
|
|||||||
<p>
|
<p>
|
||||||
send a <code>get</code> request to
|
send a <code>get</code> request to
|
||||||
<code
|
<code
|
||||||
><a href="https://chainz.ansonbiggs.com/api/alias"
|
><a href="https://2chainz.ansonbiggs.com/api/alias"
|
||||||
>https://chainz.ansonbiggs.com/api/alias</a
|
>https://2chainz.ansonbiggs.com/api/alias</a
|
||||||
></code
|
></code
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
<pre><code>{
|
<pre><code>{
|
||||||
"alias": "Dos Cadenas"
|
"alias": "Dos Cadenas"
|
||||||
}</code></pre>
|
}</code></pre>
|
||||||
</details>
|
</details>
|
||||||
<hr />
|
<hr />
|
||||||
<section>
|
<section>
|
||||||
<header>
|
<header>
|
||||||
<h2>
|
<h2>
|
||||||
Projects built using 2chainz.ansonbiggs.com (Your project could be here!)
|
Projects built using 2chainz.ansonbiggs.com (Your project could be
|
||||||
|
here!)
|
||||||
</h2>
|
</h2>
|
||||||
</header>
|
</header>
|
||||||
<aside>
|
<aside>
|
||||||
@@ -214,7 +176,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<small
|
<small
|
||||||
><a href="https://twitter.com/Anson_3D"
|
><a href="https://ansonbiggs.com/#connect"
|
||||||
>Please let me know if you use it though!</a
|
>Please let me know if you use it though!</a
|
||||||
></small
|
></small
|
||||||
>
|
>
|
||||||
@@ -224,43 +186,31 @@
|
|||||||
<h3>Do I need an API key or is this API rate limited?</h3>
|
<h3>Do I need an API key or is this API rate limited?</h3>
|
||||||
<p>
|
<p>
|
||||||
No, the API is totally free and unlimited. However, its being hosted
|
No, the API is totally free and unlimited. However, its being hosted
|
||||||
by a college student so be nice.
|
on a tiny machine that is overburdened by docker containers.
|
||||||
</p>
|
</p>
|
||||||
</aside>
|
</aside>
|
||||||
<aside>
|
<aside>
|
||||||
<h3>Is this project open source? Can I contribute?</h3>
|
<h3>Is this project open source? Can I contribute?</h3>
|
||||||
<p>
|
<p>
|
||||||
Yes and Yes! Check out the
|
Yes and Yes! Check out the
|
||||||
<a href="https://gitlab.com/2-chainz">Project on GitLab.</a>
|
<a href="https://gitlab.com/2-chainz/2chainz">Project on GitLab.</a>
|
||||||
</p>
|
</p>
|
||||||
</aside>
|
</aside>
|
||||||
<aside>
|
<aside>
|
||||||
<h3>Does 2 Chainz know about this?</h3>
|
<h3>Does 2 Chainz know about this?</h3>
|
||||||
<p>
|
<p>Probably not.</p>
|
||||||
Probably not.
|
|
||||||
</p>
|
|
||||||
</aside>
|
</aside>
|
||||||
<aside>
|
<aside>
|
||||||
<h3>Why?</h3>
|
<h3>Why?</h3>
|
||||||
<p>
|
<p>Because 2 Chainz has some of the best lines in the rap game.</p>
|
||||||
Because 2 Chainz has some of the best lines in the rap game.
|
|
||||||
</p>
|
|
||||||
</aside>
|
</aside>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
<footer>
|
<footer>
|
||||||
<hr />
|
<hr />
|
||||||
<p>
|
<p>Made by <a href="https://ansonbiggs.com">Anson</a></p>
|
||||||
Made by <a href="https://gitlab.com/MisterBiggs">Anson Biggs</a>,
|
<p>Inspired By <a href="https://kanye.rest/">kanye.rest</a>.</p>
|
||||||
<a href="https://twitter.com/Anson_3D">@Anson_3D </a>
|
<p><small>Truuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu</small></p>
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Inspired By <a href="https://kanye.rest/">kanye.rest</a> which was
|
|
||||||
created by:
|
|
||||||
<a href="https://ajzbc.com" target="_blank">Andrew Jazbec</a>,
|
|
||||||
<a href="https://twitter.com/ajzbc" target="_blank">@ajzbc</a>
|
|
||||||
</p>
|
|
||||||
<p><small>Truuuuuuuu</small></p>
|
|
||||||
</footer>
|
</footer>
|
||||||
<script>
|
<script>
|
||||||
getQuote();
|
getQuote();
|
||||||
@@ -270,13 +220,6 @@
|
|||||||
.then((resp) => resp.json())
|
.then((resp) => resp.json())
|
||||||
.then(function (data) {
|
.then(function (data) {
|
||||||
document.getElementById("quote").innerHTML = data.quote;
|
document.getElementById("quote").innerHTML = data.quote;
|
||||||
|
|
||||||
const tweet = encodeURIComponent(
|
|
||||||
`"${data.quote}" -@2chainz via https://2chainz.ansonbiggs.com`
|
|
||||||
);
|
|
||||||
document.getElementById(
|
|
||||||
"tweet"
|
|
||||||
).href = `https://twitter.com/intent/tweet?text=${tweet}`;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
fetch("/api/alias", { method: "GET" })
|
fetch("/api/alias", { method: "GET" })
|
||||||
@@ -286,6 +229,13 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script src="https://unpkg.com/ionicons@5.0.0/dist/ionicons.js"></script>
|
<script
|
||||||
|
type="module"
|
||||||
|
src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
nomodule
|
||||||
|
src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"
|
||||||
|
></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Reference in New Issue
Block a user