summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorseth <[email protected]>2023-01-09 23:34:50 -0500
committerseth <[email protected]>2023-01-09 23:34:50 -0500
commita60707fcac4e46d58199f0aa82420061572fb1b5 (patch)
tree99ee4f3978fca27d543e5c789f099df62bacdd8c
feat: initial commit
-rw-r--r--.gitattributes1
-rw-r--r--.gitignore160
-rw-r--r--.pre-commit-config.yaml20
-rw-r--r--COPYING.md14
-rw-r--r--Dockerfile8
-rw-r--r--LICENSE21
-rw-r--r--README.md5
-rw-r--r--pyproject.toml334
-rw-r--r--src/guzzle_api/__init__.py0
-rw-r--r--src/guzzle_api/api.py35
-rw-r--r--src/guzzle_api/lib.py5
-rw-r--r--src/guzzle_api/teawie/__init__.py0
-rw-r--r--src/guzzle_api/teawie/imgs/TEAWIE_FOREVER.pngbin0 -> 62056 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/__init__.py0
-rw-r--r--src/guzzle_api/teawie/imgs/catppuccin_mocha_teawie_bg.pngbin0 -> 386451 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/gifypet_basic_teawie.gifbin0 -> 7172 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/gifypet_basic_teawie.pngbin0 -> 4718 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/im_going_insane_im_going_to_snap.pngbin0 -> 540678 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/image0_png.pngbin0 -> 18820 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/inspirational_poster_wallpaper_teawie.pngbin0 -> 414954 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/midgame_to_lategame_brainfog.pngbin0 -> 824969 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/omg_hes_in_the_blender_dont_blend_him.pngbin0 -> 4214259 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/tea_sit_derp1_png.pngbin0 -> 661635 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawie.pngbin0 -> 635254 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawie_chrimas.pngbin0 -> 661156 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawie_cry.pngbin0 -> 22338 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawie_derp.pngbin0 -> 22060 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawie_dizzy.pngbin0 -> 23040 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawie_generator_concept.pngbin0 -> 48798 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawie_halloween.pngbin0 -> 691950 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawie_hydraulic_png.pngbin0 -> 313087 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawie_neutral.pngbin0 -> 21383 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawie_nommers.pngbin0 -> 497233 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawie_paint.pngbin0 -> 40150 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawie_party.pngbin0 -> 646485 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawie_pet.gifbin0 -> 31948 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawie_pet_fast.gifbin0 -> 31948 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawie_smile.pngbin0 -> 21454 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawie_smug.pngbin0 -> 20898 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawie_starstruck.pngbin0 -> 22114 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/teawiepog_new.pngbin0 -> 318300 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/this_is_how_you_look_saying_that_shit_teawie.pngbin0 -> 614155 bytes
-rw-r--r--src/guzzle_api/teawie/imgs/weird_eyes.pngbin0 -> 299567 bytes
-rw-r--r--src/guzzle_api/teawie/lib.py25
-rw-r--r--tests/test_all.py13
45 files changed, 641 insertions, 0 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..fcadb2c
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+* text eol=lf
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..68bc17f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,160 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+# For a library or package, you might want to ignore these files since the code is
+# intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+# This is especially recommended for binary packages to ensure reproducibility, and is more
+# commonly ignored for libraries.
+# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+# in version control.
+# https://pdm.fming.dev/#use-with-ide
+.pdm.toml
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+# and can be added to the global gitignore or merged into this file. For a more nuclear
+# option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..6e0c147
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,20 @@
+repos:
+- repo: https://github.com/pycqa/isort
+ rev: 5.11.2
+ hooks:
+ - id: isort
+ name: isort (python)
+
+- repo: local
+ hooks:
+ - id: pylint
+ name: pylint
+ entry: pylint
+ language: system
+ types: [python]
+
+- repo: https://github.com/pre-commit/mirrors-yapf
+ rev: "v0.32.0" # Use the sha / tag you want to point at
+ hooks:
+ - id: yapf
+ additional_dependencies: ["toml"]
diff --git a/COPYING.md b/COPYING.md
new file mode 100644
index 0000000..93d48d6
--- /dev/null
+++ b/COPYING.md
@@ -0,0 +1,14 @@
+## teawie
+
+```
+Copyright (C) 2023 SympathyTea
+
+These are licensed under the CC BY-SA 4.0 and have been unmodified
+The full license with appropriate notices is avalible at https://creativecommons.org/licenses/by-sa/4.0/
+
+Published images are as follows:
+https://commons.wikimedia.org/wiki/File:Teawie.png
+https://commons.wikimedia.org/wiki/File:Teawie_Holiday.png
+https://commons.wikimedia.org/wiki/File:Teawie_Party.png
+https://commons.wikimedia.org/wiki/File:Teawie_Halloween.png
+```
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..f424f3f
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,8 @@
+FROM python:3.9
+
+WORKDIR /code
+
+RUN pip install flit
+RUN flit install
+
+CMD [ "uvicorn", "src.guzzle_api.api:app", "--host", "0.0.0.0", "--port", "7070"]
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..cdf9e16
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 seth
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..63bf2af
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+# guzzle-api
+
+fun little service powered by [fastAPI](https://github.com/tiangolo/fastapi)
+
+right now it only serves pics of teawie
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..0b705e2
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,334 @@
+[build-system]
+requires = ["flit_core>=3.2"]
+build-backend = "flit_core.buildapi"
+
+[project]
+name = "guzzle_api"
+version = "0.0.1"
+description = "api for guzzle.gay"
+authors = [
+ { name="seth", email="[email protected]" },
+]
+readme = "README.md"
+requires-python = ">=3.9"
+dependencies = [
+ "fastapi >=0.89.0",
+ "pydantic >=1.10.0",
+ "uvicorn >=0.20.0",
+]
+
+[project.optional-dependencies]
+dev = [
+ "httpx",
+ "pre-commit",
+ "pylint",
+ "toml",
+ "yapf",
+]
+
+[project.urls]
+"Homepage" = "https://github.com/getchoo/guzzle_api"
+"Bug Tracker" = "https://github.com/getchoo/guzzle_api/issues"
+
+[tool.yapf]
+use_tabs = true
+
+[tool.pylint.main]
+# Specify a score threshold under which the program will exit with error.
+fail-under = 10
+
+# Files or directories to be skipped. They should be base names, not paths.
+ignore = ["CVS"]
+
+# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the
+# number of processors available to use, and will cap the count on Windows to
+# avoid hangs.
+jobs = 1
+
+# Control the amount of potential inferred values when inferring a single object.
+# This can help the performance when dealing with large functions or complex,
+# nested conditions.
+limit-inference-results = 100
+
+# Pickle collected data for later comparisons.
+persistent = true
+
+# Minimum Python version to use for version dependent checks. Will default to the
+# version used to run pylint.
+py-version = "3.11"
+
+# When enabled, pylint would attempt to guess common misconfiguration and emit
+# user-friendly hints instead of false-positive error messages.
+suggestion-mode = true
+
+[tool.pylint.basic]
+# Naming style matching correct argument names.
+argument-naming-style = "snake_case"
+
+# Naming style matching correct attribute names.
+attr-naming-style = "snake_case"
+
+# Bad variable names which should always be refused, separated by a comma.
+bad-names = ["foo", "bar", "baz", "toto", "tutu", "tata"]
+
+# Naming style matching correct class attribute names.
+class-attribute-naming-style = "any"
+
+# Naming style matching correct class constant names.
+class-const-naming-style = "UPPER_CASE"
+
+# Naming style matching correct class names.
+class-naming-style = "PascalCase"
+
+# Naming style matching correct constant names.
+const-naming-style = "UPPER_CASE"
+
+# Minimum line length for functions/classes that require docstrings, shorter ones
+# are exempt.
+docstring-min-length = -1
+
+# Naming style matching correct function names.
+function-naming-style = "snake_case"
+
+# Good variable names which should always be accepted, separated by a comma.
+good-names = ["i", "j", "k", "ex", "Run", "_"]
+
+# Naming style matching correct inline iteration names.
+inlinevar-naming-style = "any"
+
+# Naming style matching correct method names.
+method-naming-style = "snake_case"
+
+# Naming style matching correct module names.
+module-naming-style = "snake_case"
+
+# Regular expression which should only match function or class names that do not
+# require a docstring.
+no-docstring-rgx = "^_"
+
+# List of decorators that produce properties, such as abc.abstractproperty. Add
+# to this list to register other decorators that produce valid properties. These
+# decorators are taken in consideration only for invalid-name.
+property-classes = ["abc.abstractproperty"]
+
+# Naming style matching correct variable names.
+variable-naming-style = "snake_case"
+
+[tool.pylint.classes]
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods = ["__init__", "__new__", "setUp", "__post_init__"]
+
+# List of member names, which should be excluded from the protected access
+# warning.
+exclude-protected = ["_asdict", "_fields", "_replace", "_source", "_make"]
+
+# List of valid names for the first argument in a class method.
+valid-classmethod-first-arg = ["cls"]
+
+# List of valid names for the first argument in a metaclass class method.
+valid-metaclass-classmethod-first-arg = ["cls"]
+
+[tool.pylint.design]
+# Maximum number of arguments for function / method.
+max-args = 5
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes = 7
+
+# Maximum number of boolean expressions in an if statement (see R0916).
+max-bool-expr = 5
+
+# Maximum number of branch for function / method body.
+max-branches = 12
+
+# Maximum number of locals for function / method body.
+max-locals = 15
+
+# Maximum number of parents for a class (see R0901).
+max-parents = 7
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods = 20
+
+# Maximum number of return / yield for function / method body.
+max-returns = 6
+
+# Maximum number of statements in function / method body.
+max-statements = 50
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods = 2
+
+[tool.pylint.exceptions]
+# Exceptions that will emit a warning when caught.
+overgeneral-exceptions = ["BaseException", "Exception"]
+
+[tool.pylint.format]
+# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
+expected-line-ending-format = "LF"
+
+# Regexp for a line that is allowed to be longer than the limit.
+ignore-long-lines = "^\\s*(# )?<?https?://\\S+>?$"
+
+# Number of spaces of indent required inside a hanging or continued line.
+indent-after-paren = 4
+
+# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
+# tab).
+indent-string = " "
+
+# Maximum number of characters on a single line.
+max-line-length = 100
+
+# Maximum number of lines in a module.
+max-module-lines = 1000
+
+[tool.pylint.imports]
+# Force import order to recognize a module as part of a third party library.
+known-third-party = ["enchant"]
+
+[tool.pylint.logging]
+# The type of string formatting that logging methods do. `old` means using %
+# formatting, `new` is for `{}` formatting.
+logging-format-style = "new"
+
+# Logging modules to check that the string format arguments are in logging
+# function parameter format.
+logging-modules = ["logging"]
+
+[tool.pylint."messages control"]
+# Only show warnings with the listed confidence levels. Leave empty to show all.
+# Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, UNDEFINED.
+confidence = ["HIGH", "CONTROL_FLOW", "INFERENCE", "INFERENCE_FAILURE", "UNDEFINED"]
+
+# Disable the message, report, category or checker with the given id(s). You can
+# either give multiple identifiers separated by comma (,) or put this option
+# multiple times (only on the command line, not in the configuration file where
+# it should appear only once). You can also use "--disable=all" to disable
+# everything first and then re-enable specific checks. For example, if you want
+# to run only the similarities checker, you can use "--disable=all
+# --enable=similarities". If you want to run only the classes checker, but have
+# no Warning level messages displayed, use "--disable=all --enable=classes
+# --disable=W".
+disable = ["raw-checker-failed", "bad-inline-option", "locally-disabled", "file-ignored", "suppressed-message", "useless-suppression", "deprecated-pragma", "use-symbolic-message-instead", "missing-function-docstring", "missing-module-docstring"]
+
+# Enable the message, report, category or checker with the given id(s). You can
+# either give multiple identifier separated by comma (,) or put this option
+# multiple time (only on the command line, not in the configuration file where it
+# should appear only once). See also the "--disable" option for examples.
+enable = ["c-extension-no-member"]
+
+[tool.pylint.method_args]
+# List of qualified names (i.e., library.method) which require a timeout
+# parameter e.g. 'requests.api.get,requests.api.post'
+timeout-methods = ["requests.api.delete", "requests.api.get", "requests.api.head", "requests.api.options", "requests.api.patch", "requests.api.post", "requests.api.put", "requests.api.request"]
+
+[tool.pylint.miscellaneous]
+# List of note tags to take in consideration, separated by a comma.
+notes = ["FIXME", "XXX", "TODO"]
+
+[tool.pylint.refactoring]
+# Maximum number of nested blocks for function / method body
+max-nested-blocks = 5
+
+# Complete name of functions that never returns. When checking for inconsistent-
+# return-statements if a never returning function is called then it will be
+# considered as an explicit return statement and no message will be printed.
+never-returning-functions = ["sys.exit", "argparse.parse_error"]
+
+[tool.pylint.reports]
+# Python expression which should return a score less than or equal to 10. You
+# have access to the variables 'fatal', 'error', 'warning', 'refactor',
+# 'convention', and 'info' which contain the number of messages in each category,
+# as well as 'statement' which is the total number of statements analyzed. This
+# score is used by the global evaluation report (RP0004).
+evaluation = "max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10))"
+
+# Activate the evaluation score.
+score = true
+
+[tool.pylint.similarities]
+# Comments are removed from the similarity computation
+ignore-comments = true
+
+# Docstrings are removed from the similarity computation
+ignore-docstrings = true
+
+# Imports are removed from the similarity computation
+ignore-imports = true
+
+# Signatures are removed from the similarity computation
+ignore-signatures = true
+
+# Minimum lines number of a similarity.
+min-similarity-lines = 4
+
+[tool.pylint.spelling]
+# Limits count of emitted suggestions for spelling mistakes.
+max-spelling-suggestions = 4
+
+# List of comma separated words that should be considered directives if they
+# appear at the beginning of a comment and should not be checked.
+spelling-ignore-comment-directives = "fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy:"
+
+[tool.pylint.typecheck]
+# List of decorators that produce context managers, such as
+# contextlib.contextmanager. Add to this list to register other decorators that
+# produce valid context managers.
+contextmanager-decorators = ["contextlib.contextmanager"]
+
+# Tells whether missing members accessed in mixin class should be ignored. A
+# class is considered mixin if its name matches the mixin-class-rgx option.
+# Tells whether to warn about missing members when the owner of the attribute is
+# inferred to be None.
+ignore-none = true
+
+# This flag controls whether pylint should warn about no-member and similar
+# checks whenever an opaque object is returned when inferring. The inference can
+# return multiple potential results while evaluating a Python object, but some
+# branches might not be evaluated, which results in partial inference. In that
+# case, it might be useful to still emit no-member and other checks for the rest
+# of the inferred objects.
+ignore-on-opaque-inference = true
+
+# List of symbolic message names to ignore for Mixin members.
+ignored-checks-for-mixins = ["no-member", "not-async-context-manager", "not-context-manager", "attribute-defined-outside-init"]
+
+# List of class names for which member attributes should not be checked (useful
+# for classes with dynamically set attributes). This supports the use of
+# qualified names.
+ignored-classes = ["optparse.Values", "thread._local", "_thread._local", "argparse.Namespace"]
+
+# Show a hint with possible names when a member name was not found. The aspect of
+# finding the hint is based on edit distance.
+missing-member-hint = true
+
+# The minimum edit distance a name should have in order to be considered a
+# similar match for a missing member name.
+missing-member-hint-distance = 1
+
+# The total number of similar names that should be taken in consideration when
+# showing a hint for a missing member.
+missing-member-max-choices = 1
+
+# Regex pattern to define which classes are considered mixins.
+mixin-class-rgx = ".*[Mm]ixin"
+
+[tool.pylint.variables]
+# Tells whether unused global variables should be treated as a violation.
+allow-global-unused-variables = true
+
+# List of strings which can identify a callback function by name. A callback name
+# must start or end with one of those strings.
+callbacks = ["cb_", "_cb"]
+
+# A regular expression matching the name of dummy variables (i.e. expected to not
+# be used).
+dummy-variables-rgx = "_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_"
+
+# Argument names that match this expression will be ignored.
+ignored-argument-names = "_.*|^ignored_|^unused_"
+
+# List of qualified module names which can have objects that can redefine
+# builtins.
+redefining-builtins-modules = ["six.moves", "past.builtins", "future.builtins", "builtins", "io"]
diff --git a/src/guzzle_api/__init__.py b/src/guzzle_api/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/guzzle_api/__init__.py
diff --git a/src/guzzle_api/api.py b/src/guzzle_api/api.py
new file mode 100644
index 0000000..d0770f0
--- /dev/null
+++ b/src/guzzle_api/api.py
@@ -0,0 +1,35 @@
+from fastapi import FastAPI, Query
+from fastapi.staticfiles import StaticFiles
+
+from guzzle_api import lib
+from guzzle_api.teawie import lib as teawie
+
+URL = "https://guzzle.gay/api"
+TEAWIE_STATIC_ENDPOINT = "/static/teawie"
+
+app = FastAPI()
+
+app.mount(TEAWIE_STATIC_ENDPOINT,
+ StaticFiles(packages=[("guzzle_api.teawie.imgs", "")]),
+ name="teawie_pics")
+
+
[email protected]("/list_teawies")
+async def teawie_list(limit: str | None = Query(default="5", max="2")):
+ try:
+ limit = int(limit)
+ except ValueError:
+ return {"error": "invalid limit"}
+
+ res = {}
+ for key, value in enumerate(teawie.list_teawies(limit)):
+ res[key] = lib.path_to_json_val(URL, TEAWIE_STATIC_ENDPOINT, value)
+
+ return res
+
+
[email protected]("/get_random_teawie")
+async def get_random_teawie():
+ tea = teawie.random_teawie()
+ value = lib.path_to_json_val(URL, TEAWIE_STATIC_ENDPOINT, tea)
+ return {"url": f"{value}"}
diff --git a/src/guzzle_api/lib.py b/src/guzzle_api/lib.py
new file mode 100644
index 0000000..18ef32a
--- /dev/null
+++ b/src/guzzle_api/lib.py
@@ -0,0 +1,5 @@
+from pathlib import Path
+
+
+def path_to_json_val(url: str, mount: str, file_path: Path) -> str:
+ return f"{url}{mount}/{file_path.name}"
diff --git a/src/guzzle_api/teawie/__init__.py b/src/guzzle_api/teawie/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/guzzle_api/teawie/__init__.py
diff --git a/src/guzzle_api/teawie/imgs/TEAWIE_FOREVER.png b/src/guzzle_api/teawie/imgs/TEAWIE_FOREVER.png
new file mode 100644
index 0000000..54fc6e7
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/TEAWIE_FOREVER.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/__init__.py b/src/guzzle_api/teawie/imgs/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/__init__.py
diff --git a/src/guzzle_api/teawie/imgs/catppuccin_mocha_teawie_bg.png b/src/guzzle_api/teawie/imgs/catppuccin_mocha_teawie_bg.png
new file mode 100644
index 0000000..7d3a083
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/catppuccin_mocha_teawie_bg.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/gifypet_basic_teawie.gif b/src/guzzle_api/teawie/imgs/gifypet_basic_teawie.gif
new file mode 100644
index 0000000..84ebe80
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/gifypet_basic_teawie.gif
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/gifypet_basic_teawie.png b/src/guzzle_api/teawie/imgs/gifypet_basic_teawie.png
new file mode 100644
index 0000000..95d2684
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/gifypet_basic_teawie.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/im_going_insane_im_going_to_snap.png b/src/guzzle_api/teawie/imgs/im_going_insane_im_going_to_snap.png
new file mode 100644
index 0000000..c9871bb
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/im_going_insane_im_going_to_snap.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/image0_png.png b/src/guzzle_api/teawie/imgs/image0_png.png
new file mode 100644
index 0000000..0f04441
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/image0_png.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/inspirational_poster_wallpaper_teawie.png b/src/guzzle_api/teawie/imgs/inspirational_poster_wallpaper_teawie.png
new file mode 100644
index 0000000..08716bd
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/inspirational_poster_wallpaper_teawie.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/midgame_to_lategame_brainfog.png b/src/guzzle_api/teawie/imgs/midgame_to_lategame_brainfog.png
new file mode 100644
index 0000000..a7a2247
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/midgame_to_lategame_brainfog.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/omg_hes_in_the_blender_dont_blend_him.png b/src/guzzle_api/teawie/imgs/omg_hes_in_the_blender_dont_blend_him.png
new file mode 100644
index 0000000..79b9d80
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/omg_hes_in_the_blender_dont_blend_him.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/tea_sit_derp1_png.png b/src/guzzle_api/teawie/imgs/tea_sit_derp1_png.png
new file mode 100644
index 0000000..9782213
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/tea_sit_derp1_png.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawie.png b/src/guzzle_api/teawie/imgs/teawie.png
new file mode 100644
index 0000000..c4815a0
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawie.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawie_chrimas.png b/src/guzzle_api/teawie/imgs/teawie_chrimas.png
new file mode 100644
index 0000000..c899523
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawie_chrimas.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawie_cry.png b/src/guzzle_api/teawie/imgs/teawie_cry.png
new file mode 100644
index 0000000..1ac793b
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawie_cry.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawie_derp.png b/src/guzzle_api/teawie/imgs/teawie_derp.png
new file mode 100644
index 0000000..45a8dd3
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawie_derp.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawie_dizzy.png b/src/guzzle_api/teawie/imgs/teawie_dizzy.png
new file mode 100644
index 0000000..04c28c9
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawie_dizzy.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawie_generator_concept.png b/src/guzzle_api/teawie/imgs/teawie_generator_concept.png
new file mode 100644
index 0000000..ee5b429
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawie_generator_concept.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawie_halloween.png b/src/guzzle_api/teawie/imgs/teawie_halloween.png
new file mode 100644
index 0000000..bd66661
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawie_halloween.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawie_hydraulic_png.png b/src/guzzle_api/teawie/imgs/teawie_hydraulic_png.png
new file mode 100644
index 0000000..08d4a25
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawie_hydraulic_png.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawie_neutral.png b/src/guzzle_api/teawie/imgs/teawie_neutral.png
new file mode 100644
index 0000000..4c2c49d
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawie_neutral.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawie_nommers.png b/src/guzzle_api/teawie/imgs/teawie_nommers.png
new file mode 100644
index 0000000..ad69f50
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawie_nommers.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawie_paint.png b/src/guzzle_api/teawie/imgs/teawie_paint.png
new file mode 100644
index 0000000..2b3baeb
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawie_paint.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawie_party.png b/src/guzzle_api/teawie/imgs/teawie_party.png
new file mode 100644
index 0000000..8f9434a
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawie_party.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawie_pet.gif b/src/guzzle_api/teawie/imgs/teawie_pet.gif
new file mode 100644
index 0000000..782722a
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawie_pet.gif
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawie_pet_fast.gif b/src/guzzle_api/teawie/imgs/teawie_pet_fast.gif
new file mode 100644
index 0000000..5123e99
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawie_pet_fast.gif
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawie_smile.png b/src/guzzle_api/teawie/imgs/teawie_smile.png
new file mode 100644
index 0000000..e9d3f3c
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawie_smile.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawie_smug.png b/src/guzzle_api/teawie/imgs/teawie_smug.png
new file mode 100644
index 0000000..8d9f1d0
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawie_smug.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawie_starstruck.png b/src/guzzle_api/teawie/imgs/teawie_starstruck.png
new file mode 100644
index 0000000..27edd30
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawie_starstruck.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/teawiepog_new.png b/src/guzzle_api/teawie/imgs/teawiepog_new.png
new file mode 100644
index 0000000..c134030
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/teawiepog_new.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/this_is_how_you_look_saying_that_shit_teawie.png b/src/guzzle_api/teawie/imgs/this_is_how_you_look_saying_that_shit_teawie.png
new file mode 100644
index 0000000..5e9961c
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/this_is_how_you_look_saying_that_shit_teawie.png
Binary files differ
diff --git a/src/guzzle_api/teawie/imgs/weird_eyes.png b/src/guzzle_api/teawie/imgs/weird_eyes.png
new file mode 100644
index 0000000..7181e0f
--- /dev/null
+++ b/src/guzzle_api/teawie/imgs/weird_eyes.png
Binary files differ
diff --git a/src/guzzle_api/teawie/lib.py b/src/guzzle_api/teawie/lib.py
new file mode 100644
index 0000000..2dd452c
--- /dev/null
+++ b/src/guzzle_api/teawie/lib.py
@@ -0,0 +1,25 @@
+import importlib.resources
+import random
+from math import ceil
+from pathlib import Path
+
+from guzzle_api.teawie import imgs
+
+NUM_TEAWIES = 30
+
+
+def list_teawies(limit: int) -> list[Path]:
+ files = importlib.resources.files(imgs)
+
+ res = []
+ for i, file in enumerate(files.iterdir()):
+ if i >= limit:
+ break
+ res.append(file)
+
+ return res
+
+
+def random_teawie() -> Path:
+ limit = ceil(NUM_TEAWIES / 2)
+ return random.choice(list_teawies(limit))
diff --git a/tests/test_all.py b/tests/test_all.py
new file mode 100644
index 0000000..3a405eb
--- /dev/null
+++ b/tests/test_all.py
@@ -0,0 +1,13 @@
+from fastapi.testclient import TestClient
+
+from guzzle_api.api import app
+
+client = TestClient(app)
+
+resp = client.get("/get_random_teawie").text
+print(f"random:\n {resp}")
+
+resp = client.get("/list_teawies?limit=6").text
+print(f"list:\n {resp}")
+
+tests = {"/list_teawies"}