Skip to content

Commit b37911d

Browse files
Merge pull request #60 from takos22/challenges
Add challenge language endpoints
2 parents 6e7bd82 + be4f676 commit b37911d

File tree

17 files changed

+828
-44
lines changed

17 files changed

+828
-44
lines changed

Pipfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pytest-asyncio = "*"
1515
[packages]
1616
pyjwt = "*"
1717
postdb = "*"
18-
aiohttp = "*"
18+
aiohttp = "~=3.7"
1919
fastapi = "*"
2020
aioredis = "*"
2121
fakeredis = "*"

Pipfile.lock

Lines changed: 116 additions & 33 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ pipenv install --dev
7272

7373
### Environment variables
7474

75+
#### Required
76+
7577
Start by writing this in a file named `.env`:
7678

7779
```prolog
@@ -85,15 +87,22 @@ DISCORD_CLIENT_SECRET=
8587
And fill in the variables with the values below:
8688

8789
- `REDIS_URI` is the Redis server URI.
88-
- `POSTGRES_URI` is the PostgreSQL database URI.
8990
- `SECRET_KEY` is the key used for JWT token encoding.
90-
- `TEST_REDIS_URU` is the Connection URI for Redis testing server.
91-
- `TEST_POSTGRES_URI` is the PostgreSQL database URI for tests.
91+
- `POSTGRES_URI` is the PostgreSQL database URI.
9292
- `DISCORD_CLIENT_ID` is the Discord application ID. Copy it from your Discord application page (see below).
9393
- `DISCORD_CLIENT_SECRET` is the Discord application secret. Copy it from your Discord application page (see below).
9494

9595
![Client ID and secret](https://cdn.discordapp.com/attachments/721750194797936823/794646777840140298/unknown.png)
9696

97+
#### Optional
98+
99+
For testing you need to add these environment variables:
100+
101+
- `TEST_REDIS_URI` is the Connection URI for Redis testing server.
102+
- `TEST_POSTGRES_URI` is the PostgreSQL database URI for tests.
103+
104+
If you are self hosting the Piston API, you need to set the `PISTON_URL` environment variable.
105+
97106
### Running
98107

99108
Run the API and initialise the database:

api/services/http.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
from typing import Optional
33

44

5-
session: Optional[ClientSession] = None
5+
__all__ = ("session",)
66

7-
__all__ = (session,)
7+
session: Optional[ClientSession] = None

api/services/piston.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import logging
2+
from typing import Any, Dict, List
3+
4+
import config
5+
from api.services import http
6+
7+
8+
__all__ = ("get_runtimes", "get_runtimes_dict", "get_runtime", "Runtime")
9+
10+
log = logging.getLogger()
11+
12+
_base_url: str = (
13+
config.piston_url().rstrip("/") + "/"
14+
) # make sure there's a / at the end
15+
16+
17+
async def _make_request(method: str, endpoint: str, data: Any = None) -> Any:
18+
async with http.session.request(
19+
method,
20+
_base_url + endpoint,
21+
json=data,
22+
raise_for_status=True,
23+
) as response:
24+
return await response.json()
25+
26+
27+
async def get_runtimes() -> List["Runtime"]:
28+
"""Get a list of all available runtimes."""
29+
runtimes = await _make_request("GET", "runtimes")
30+
return [Runtime(runtime) for runtime in runtimes]
31+
32+
33+
async def get_runtimes_dict() -> Dict[str, List["Runtime"]]:
34+
"""Get a dictionary of language names and aliases mapped to a list of
35+
all the runtimes with that name or alias.
36+
"""
37+
38+
runtimes = await get_runtimes()
39+
runtimes_dict = {}
40+
41+
for runtime in runtimes:
42+
if runtime.language in runtimes_dict:
43+
runtimes_dict[runtime.language].append(runtime)
44+
else:
45+
runtimes_dict[runtime.language] = [runtime]
46+
47+
for alias in runtime.aliases:
48+
if alias in runtimes_dict:
49+
runtimes_dict[alias].append(runtime)
50+
else:
51+
runtimes_dict[alias] = [runtime]
52+
53+
return runtimes_dict
54+
55+
56+
async def get_runtime(language: str) -> List["Runtime"]:
57+
"""Get a runtime with a language or an alias."""
58+
59+
runtimes_dict = await get_runtimes_dict()
60+
return runtimes_dict.get(language, [])
61+
62+
63+
class Runtime:
64+
def __init__(self, data: dict):
65+
self.language = data["language"]
66+
self.version = data["version"]
67+
self.aliases = data["aliases"]
68+
self.runtime = data.get("runtime")

api/services/redis.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import json
77

88

9+
__all__ = ("pool",)
10+
911
log = logging.getLogger(__name__)
1012

1113

@@ -22,6 +24,3 @@ async def dispatch(channel: ChannelT, message: Union[EncodableT, list, dict]) ->
2224

2325

2426
pool: Optional[Union[FakeRedis, Redis]] = None
25-
26-
27-
__all__ = (pool,)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from . import languages
2+
from .routes import router
3+
4+
router.include_router(languages.router)
5+
6+
__all__ = (router,)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .routes import router
2+
3+
__all__ = (router,)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from fastapi import HTTPException
2+
3+
from api.services import piston
4+
5+
6+
async def check_piston_language_version(language: str, version: str):
7+
"""Checks if a language and its version are installed on the Piston service.
8+
9+
Raises an :class:`fastapi.HTTPException` otherwise with a 404 status code.
10+
"""
11+
12+
runtimes = await piston.get_runtime(language)
13+
if not runtimes:
14+
raise HTTPException(404, "Piston language not found")
15+
16+
versions = [runtime.version for runtime in runtimes]
17+
if version not in versions:
18+
raise HTTPException(404, "Piston language version not found")

0 commit comments

Comments
 (0)