Skip to content

Commit

Permalink
Merge pull request #31 from pietrzakacper/python-reporter
Browse files Browse the repository at this point in the history
Python reporter
  • Loading branch information
pietrzakacper authored Sep 22, 2024
2 parents 4c9074e + a9506d4 commit b4b937b
Show file tree
Hide file tree
Showing 35 changed files with 854 additions and 83 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,15 @@ jobs:
uses: actions/setup-go@v4
with:
go-version: "1.21.7"
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- uses: oven-sh/setup-bun@v2
- run: go mod tidy
- run: cd reporters/golang && go mod tidy && cd ../..
- run: cd reporters/javascript/tracethat.dev && bun install && bun run build && cd ../..
- run: cd reporters/python && ./install.sh && cd ../..
- run: cd frontend && bun install && cd ../..
- run: cd e2e-tests && bun install && bunx playwright install --with-deps chromium && cd ../..
- run: cd e2e-tests && bun run test && cd ../..
Expand Down
24 changes: 24 additions & 0 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,27 @@ jobs:
- run: cd reporters/javascript/tracethat.dev && bun install && bun run build && cd ../..
- run: cd reporters/javascript/integration-tests && npm ci && cd ../../..
- run: cd reporters/javascript/integration-tests && npm run test | bunx tap-spec && cd ../../..

python-tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["pypy3.9", "pypy3.10", "3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
cd reporters/python
./install.sh
cd ../..
- name: Run tests
run: |
cd reporters/python
source .venv/bin/activate
python -m unittest discover -p '*_test.py'
cd ../..
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ For now only Unix/MacOS are supported for local development
- go (https://go.dev/doc/install) - tested with `go1.21.7`
- bun (https://bun.sh/docs/installation) - tested with `1.0.29`
- node/npm (https://nodejs.org/en/download) - tested with `v20.11.0`
- python3 (https://www.python.org/downloads/) - tested with `3.12.0`

### Golang Server

Expand Down Expand Up @@ -58,6 +59,17 @@ cd example
TT_SERVER_URL=ws://localhost:3000 TT_TOKEN=123 go run ./...
```

### Python Reporter

In `./reporters/python`

```bash
./install.sh # install dependencies
source .venv/bin/activate # activate virtual environment
python3 example.py # run the example using locally built reporter and local server
deactivate
```

### E2E tests

In `e2e-tests` directory:
Expand Down
Binary file modified e2e-tests/bun.lockb
Binary file not shown.
5 changes: 4 additions & 1 deletion e2e-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
},
"description": "",
"scripts": {
"install": "cd tests/javascript-web/reporter && bun install && cd ../../javascript-server/reporter && bun install ",
"install": "bun run install:js-web && bun run install:js-server && bun run install:python-server",
"install:js-web": "cd tests/javascript-web/reporter && bun install && cd ../../..",
"install:js-server": "cd tests/javascript-server/reporter && bun install && cd ../../..",
"install:python-server": "cd tests/python-server/reporter && ./install.sh && cd ../../..",
"build-frontend": "cd ../frontend && VITE_SERVER_URL=/ bun run build",
"build-js-reporter": "cd ../reporters/javascript/tracethat.dev && bun run build",
"pretest": "bun run build-js-reporter && bun run build-frontend",
Expand Down
Binary file modified e2e-tests/tests/javascript-web/reporter/bun.lockb
Binary file not shown.
32 changes: 32 additions & 0 deletions e2e-tests/tests/python-server/python-server.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { expect, test } from "@playwright/test";
import { runServer } from "../utils";
import child_process from "child_process";
import util from "util";
import path from "path";

const exec = util.promisify(child_process.exec);

const TOKEN = "test-token";
const TEST_NAME = "barry";

let serverProcess: child_process.ChildProcess;

test("send hello from Python server", async ({ page }) => {
let serverPort: number;
[serverProcess, serverPort] = await runServer(3500);

await page.goto(`http://localhost:${serverPort}`);
await page.getByPlaceholder("Enter session ID").fill(TOKEN);
await page.getByRole("button", { name: "Go" }).click();

await exec(`./start.sh ${TEST_NAME}`, {
env: { ...process.env, TT_TOKEN: TOKEN, TT_SERVER_URL: `ws://localhost:${serverPort}` },
cwd: path.join(__dirname, "reporter"),
});

await expect(page.getByText(`hello ${TEST_NAME}`)).toBeVisible();
});

test.afterAll(() => {
serverProcess?.kill();
});
1 change: 1 addition & 0 deletions e2e-tests/tests/python-server/reporter/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.venv
5 changes: 5 additions & 0 deletions e2e-tests/tests/python-server/reporter/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
python3 -m venv .venv
source .venv/bin/activate
pip install -e ../../../../reporters/python
deactivate
14 changes: 14 additions & 0 deletions e2e-tests/tests/python-server/reporter/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import time
import sys
from tracethat import tracethat

@tracethat
def hello(name: str, greeting='Hello') -> str:
time.sleep(1)
return f'{greeting} {name}'

def main():
hello(sys.argv[1])

if __name__ == '__main__':
main()
5 changes: 5 additions & 0 deletions e2e-tests/tests/python-server/reporter/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

source .venv/bin/activate
python3 main.py $1
deactivate
Binary file modified frontend/bun.lockb
Binary file not shown.
2 changes: 2 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tabs": "^1.1.0",
"@radix-ui/react-tooltip": "^1.0.7",
"@tanstack/react-table": "^8.12.0",
"class-variance-authority": "^0.7.0",
Expand All @@ -23,6 +24,7 @@
"prism-react-renderer": "^2.3.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^5.3.0",
"react-json-tree": "^0.18.0",
"react-json-view": "^1.21.3",
"tailwind-merge": "^2.2.1",
Expand Down
Binary file added frontend/src/assets/logos/python.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 41 additions & 16 deletions frontend/src/components/HighlightedCode.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,60 @@
import { cn } from "@/lib/utils";
import { Highlight, themes } from "prism-react-renderer";
import { useTheme } from "./ui/theme-provider";
import { useMemo } from "react";
import { useMemo, useState } from "react";
import { FiClipboard, FiCheck } from "react-icons/fi";

interface HighlightedCodeProps {
code: string;
language: string;
className?: string;
}

export const HighlightedCode = ({ code, language, className: externalClassName }: HighlightedCodeProps) => {
const theme = useTheme();
const highlightTheme = useMemo(() => (theme.theme === "light" ? themes.oneLight : themes.oneDark), [theme.theme]);

const [isCopied, setIsCopied] = useState(false);

const handleCopyClick = () => {
navigator.clipboard.writeText(code).then(
() => {
setIsCopied(true);
setTimeout(() => setIsCopied(false), 2000);
},
(err) => {
console.error("Failed to copy!", err);
},
);
};

return (
<Highlight theme={highlightTheme} code={code} language={language}>
{({ className, tokens, getLineProps, getTokenProps }) => (
<pre
className={cn(
className,
"font-mono text-left py-5 px-6 rounded-sm bg-muted text-foreground select-text overflow-auto",
externalClassName,
)}
>
{tokens.map((line, i) => (
<div key={i} {...getLineProps({ line })}>
{line.map((token, key) => (
<span key={key} {...getTokenProps({ token })} />
))}
</div>
))}
</pre>
<div className="relative group">
<pre
className={cn(
className,
"font-mono text-left py-5 px-6 rounded-sm bg-muted text-foreground select-text overflow-auto",
externalClassName,
)}
>
{tokens.map((line, i) => (
<div key={i} {...getLineProps({ line })}>
{line.map((token, key) => (
<span key={key} {...getTokenProps({ token })} />
))}
</div>
))}
</pre>
<button
onClick={handleCopyClick}
aria-label="Copy code to clipboard"
className="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity bg-gray-200 text-gray-800 p-1 rounded"
>
{isCopied ? <FiCheck className="w-5 h-5" /> : <FiClipboard className="w-5 h-5" />}
</button>
</div>
)}
</Highlight>
);
Expand Down
40 changes: 19 additions & 21 deletions frontend/src/components/Snippet/Snippet.constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import jsLogo from "@/assets/logos/js.png";
import goLogo from "@/assets/logos/go.png";
import pythonLogo from "@/assets/logos/python.png";

const getJavaScriptBlock = (token: string) =>
`
Expand All @@ -14,29 +15,22 @@ const hello = (name) => {
traceThat(hello)("world");
`.trim();

const getTypeScriptBlock = (token: string) =>
`
import { traceThat, registerToken } from "tracethat.dev";
registerToken("${token}");
const hello = (name: string) => {
return \`Hello \${name}!\`;
}
traceThat(hello)("world");
`.trim();

const getPythonBlock = (token: string) =>
`
from tracethat_dev import trace_that, register_token
import asyncio
from tracethat import tracethat, register_token
register_token('${token}')
def hello(name):
return f'Hello {name}!'
@tracethat
async def hello(name: str) -> str:
await asyncio.sleep(1)
return f'Hello, {name}!'
async def main():
await hello(name='world')
trace_that(hello)('world')
asyncio.run(main())
`.trim();

const getGoBlock = (token: string) =>
Expand Down Expand Up @@ -65,22 +59,26 @@ func main() {

const CODE_BLOCKS = {
js: getJavaScriptBlock,
ts: getTypeScriptBlock,
python: getPythonBlock,
go: getGoBlock,
};
const INSTALLATION_CODE_BLOCKS = {
js: "npm install tracethat.dev",
python: "pip install tracethat",
go: "go get github.com/pietrzakacper/tracethat.dev/reporters/golang/tt",
};
export type AvailableLanguage = keyof typeof CODE_BLOCKS;
interface LanguageDisplayData {
name: string;
logo: string;
}
const DISPLAY_DATA: Record<AvailableLanguage, LanguageDisplayData> = {
js: { name: "JavaScript", logo: jsLogo },
ts: { name: "TypeScript", logo: jsLogo },
python: { name: "Python", logo: jsLogo },
python: { name: "Python", logo: pythonLogo },
go: { name: "Go", logo: goLogo },
};

export const getInstallationSnippet = (language: AvailableLanguage) => INSTALLATION_CODE_BLOCKS[language];
export const getSnippet = (language: AvailableLanguage, token: string) => CODE_BLOCKS[language](token);
export const SHOWN_LANGUAGES: AvailableLanguage[] = ["js", "go"];
export const SHOWN_LANGUAGES: AvailableLanguage[] = ["js", "python", "go"];
export const getDisplayData = (language: AvailableLanguage) => DISPLAY_DATA[language];
69 changes: 24 additions & 45 deletions frontend/src/components/Snippet/Snippet.tsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,33 @@
import { useMemo, useState } from "react";
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from "../ui/dropdown-menu";
import { AvailableLanguage, SHOWN_LANGUAGES, getDisplayData, getSnippet } from "./Snippet.constants";
import { Button } from "../ui/button/button";
import { ChevronDown } from "lucide-react";
import { SHOWN_LANGUAGES, getDisplayData, getInstallationSnippet, getSnippet } from "./Snippet.constants";
import { HighlightedCode } from "../HighlightedCode";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/tabs";

interface SnippetProps {
token: string;
}
export const Snippet = ({ token }: SnippetProps) => {
const [language, setLanguage] = useState<AvailableLanguage>("js");
const code = useMemo(() => getSnippet(language, token), [language, token]);

const selectedButton = useMemo(() => {
const { logo, name } = getDisplayData(language);
return (
<Button variant="outline" size="sm" className="px-1">
<div className="relative">
<img src={logo} alt={name} className="h-5 aspect-square rounded-tiny" />
<div className="fill-absolute ring-1 ring-primary/10 ring-inset rounded-tiny" />
</div>
<ChevronDown className="ml-1 h-4 w-4" />
</Button>
);
}, [language]);

return (
<div className="relative">
<div className="absolute top-2 right-2">
<DropdownMenu>
<DropdownMenuTrigger asChild>{selectedButton}</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{SHOWN_LANGUAGES.map((lang) => {
const { logo, name } = getDisplayData(lang);

return (
<DropdownMenuItem key={lang} onClick={() => setLanguage(lang)}>
<div className="relative">
<img src={logo} alt={name} className="w-6 aspect-square rounded-tiny" />
<div className="fill-absolute ring-1 ring-primary/10 ring-inset rounded-tiny" />
</div>
<span className="ml-2">{name}</span>
</DropdownMenuItem>
);
})}
</DropdownMenuContent>
</DropdownMenu>
</div>

<HighlightedCode code={code} language={language} />
</div>
<Tabs defaultValue={SHOWN_LANGUAGES[0]} className="flex flex-col w-full items-end">
<TabsList>
{SHOWN_LANGUAGES.map((language) => {
const { logo, name } = getDisplayData(language);
return (
<TabsTrigger key={language} value={language}>
<div className="relative">
<img src={logo} alt={name} className="w-6 aspect-square rounded-tiny" />
<div className="fill-absolute ring-1 ring-primary/10 ring-inset rounded-tiny" />
</div>
</TabsTrigger>
);
})}
</TabsList>
{SHOWN_LANGUAGES.map((language) => (
<TabsContent key={language} value={language} className="w-full">
<HighlightedCode language="bash" code={getInstallationSnippet(language)} />
<br />
<HighlightedCode language={language} code={getSnippet(language, token)} />
</TabsContent>
))}
</Tabs>
);
};
Loading

0 comments on commit b4b937b

Please sign in to comment.