I mirrored all the code from PyPI to GitHub and analysed it (py-code.org)
This is a side project I've been working on for the last few months. I built an automated system to continuously mirror all the code on PyPI to a series of Github repositories. Mirroring PyPI code to Github enables:
1. Scanning of all new Python packages for accidentally published credentials
2. A browsable/searchable index of published code with a nice UI
3. Large-scale analysis of all published code to see how the language is evolving
Using this project anyone is able to download the contents of PyPI to their personal machine and analyse every piece of code ever published in a matter of hours.
I hope it enables people to do things with the worlds largest and oldest corpus of Python code that wasn't possible before, and while this is likely totally useless to most people I think that is kind of cool and unique.
130 comments
[ 2.8 ms ] story [ 195 ms ] threadI’m working on distributing this data without GitHub - git packfiles are a fantastic way of compressing this data, and you can serve those easily enough from a bucket.
1. https://peps.python.org/pep-0654/
BTW RealPython is quite boring about wanting you to create an account, I'm sure they didn't use to be as bad but I can barely read that page in its entirety without getting forced to create an account.
as a python oldie coming back into python, i've been surprised by dataclasses. are they basically "backwards compatible better classes"? any strong blogposts or readings that people can share about better typed python/OSS module publishing practices?
Dataclasses are nice - they are a pared down version of the attrs library, so a simple way to create data-only or mainly-data records through classes. They are not intended to replace all classes.
[0] https://blog.glyph.im/2023/02/data-classification.html
Will Microsoft see this as a free license to use all of PyPI?
Code which has a "can't be placed on github" license restriction is definitely not open source, regardless of what other terms the license purports to have.
If trying to prevent your software from being used to create proprietary software makes it not open-source, is the ONU GPL not an open-source license?
It's a fallback clause, "fair use" is irrelevant if you've already given github permission to use it. By adding that clause you can no longer argue that it's not fair use to use the code you put on github after agreeing to their terms.
Your reciprocity suggestion could also work, since it would mean any LLM trained on even a single file of GPL code would be "poisoned" in the sense that any code it produced would also be GPL. This would make people wary of using the LLM for writing code, and thus would make the creators of it wary of training it on the code.
Now just because you don't understand a language model and call its fitting procedure 'learning' doesn't mean that it is doing anything even remotely similar. And even if it does then it has no legal responsibilities so if you want to distribute it then you as the distributor need to assume responsibility for all the copyrights such an act could possibly infringe.
There are measures you can take to try to prevent the information from any one code base from entering the model verbatim, by severely restricting the model size or carefully obfuscating the data, but to my knowledge nobody has used any method that gives any proven measure of security.
AI wont include it, user wont know it should be GPL, developer wont know it was stolen.
This is a whole can of problematic worms
But to be honest, this is a non-issue. Copilot (and co) rarely outputs copyrighted code verbatim and when it does, it's usually too small or too trivial to fall under copyright protection. I made a prediction last year that no one will get sued from using Copilot generated code and I believe it has held so far[0].
[0] https://news.ycombinator.com/item?id=31849027
I also know how they learn. And I know how the biological brain learns. The differences are just technical. The underlying concept is really the same: Both learn by adjusting the neuronal strengths between neurons based on what they see.
Legal responsibilities is sth different. This is up to politics to decide.
My argument is purely on the fact that what humans do and what machines do is extremely similar, and the differences are just technical and don't really matter here. This is often misunderstood by people who think that machines don't really learn like humans.
You can’t use a license to bind people who don't need a license.
One can argue about ToS and copyright, about different interpretations of fair use, derivative work, DRM protections, and so on. Usually people are not interested to discuss finer details of those things. Most people seems to want to perceive it as either being public or not public, in which case, Youtube is just as public as PyPi.
Copilot was trained on Github code under a “training models doesn’t require permission” theory before there was anything about it in the ToS, and basically every other large model has taken a similar approach to publicly-accessible data of all kinds.
> Will Microsoft see this as a free license to use all of PyPI
Microsoft doesn’t think they need a license for model training.
This is a perfect job for task-spooler! :D
To mirror your pypi data, I sshed into my server and did this:
And then I closed the ssh connection to my server, knowing that my server will proceed to mirror all of those repositories of yours one by one :D(Or you could also run your way in tmux or screen.)
With task-spooler, it puts all of the commands (in this case, the individual git clone commands for each of the repos) in a queue and it runs the commands independently of my ssh session, so I can quickly add a bunch of jobs like this to the queue and immediately disconnect my ssh session.
Seems like PyPi explicitly allows this behavior:
"If I upload Content covered by a royalty-free license included with such Content, giving the PSF the right to copy and redistribute such Content unmodified on PyPI as I have uploaded it, with no further action required by the PSF (an "Included License"), I represent and warrant that the uploaded Content meets all the requirements necessary for free redistribution by the PSF and any mirroring facility, public or private, under the Included License.
If I upload Content other than under an Included License, then I grant the PSF and all other users of the web site an irrevocable, worldwide, royalty-free, nonexclusive license to reproduce, distribute, transmit, display, perform, and publish the Content, including in digital form."
This means no analysis has been done on the contents of PyPI. In turn this means malicious packages are harder to detect (and for sure still present somewhere in there), it means people publish an absolutely crazy number of credentials to PyPI on a daily basis without ever knowing (+ no simple way to find concrete ways to improve this) and it means there is a lack of exploration on the impacts of language features/changes on the ecosystem.
To me the GitHub aspect isn't important or interesting. Would it make any difference if it was distributed from a series of git repositories hosted on S3? It's the git apsect that is interesting, because it lowers the barrier for anyone to access the corpus of already public, already mirrored and already automatically-scanned-by-bad-actors code that is on PyPI.
While this project is more "a number of things glued-together" than "a groundbreaking invention", I have to disagree with the triviality aspect. Most problems we deal with can be reduced to 'copying X from one place to another' (sorting?), and the devil is always in the details.
> I don't like this, it's this kind of stunt that makes me reluctant to publish my code in general.
Isn't this quite circular? People using code you publish publicly makes you reluctant to publish code publicly?
Not that I disagree with this project, but just to maybe help see it from a little different perspective...
When people publish their code, I think they typically expect it's going to be used like
So it is a little weird when things like this come along and change that expectation.It's kind of like, "I scanned millions of Facebook photos for soda cans to see if people prefer Pepsi or Coke!" People didn't post those photos be be part of a project, they just wanted to share some pictures with their friends.
It doesn't really matter whether its a public repository or if you use thing your friends shared only within their network. When it comes to what people expect and how they'll feel about breaking those expectations, the only difference is that a smaller network of generally like-minded people _may_ already be cool with it, or at least it's easier to ask.
I'm not even saying they're right to feel weird about it. Just that people are going to feel what they're going to feel, and doing something they didn't expect is a sure-fire way to get them to feel _something_.
I'm not really sold on the perspective that if you're a sophisticated enough developer to know+upload+publish on pypi that you wouldn't expect someone to read your code. In many ways that's kind of the point. Not to say such people don't exist, but they're probably a small minority.
[0]: https://cyble.com/blog/over-45-thousand-users-fell-victim-to...
I mean, sure, compared to the 478,876 Projects claimed on https://pypi.org/, that's a pretty small minority. On the other hand, I'd guess many Python packages don't use these particular services, or even need to connect to a remote service at all, so the area for this class of mistake should be smaller.
And mistakes do happen, but that's a pretty big thing to miss if you are knowingly publishing your code with the expectation other people will be reading it.
In the future, rather than shit on someone’s project, read.
Spoiler: the answer is nightly builds, huge binaries and a lot of wheels per release.
And pip install some tensor flow nonsense has broken my projects many, many times. At this point I try really hard to ever avoid depending on anything in that ecosystem.
For example, here is one service that is able to generate various canary tokens: https://www.canarytokens.org/generate
Or as another example, someone who wants to research how often people copy paste example config files without replacing things like credentials given in the example.
Probably a bunch of other reasons too.
So you found 57 live AWS keys[1]. That's out of 1631 according to your stats (If I didn't misread something). I wonder how many of the top two in the list are live :D
Google API Key 4,015 OpenAI API Key 3,531
[1] https://tomforb.es/i-scanned-every-package-on-pypi-and-found...
The project that leverages GitHub secret scanning found a lot more.
There is a search page where I can look up which repo a specific version of a specific PyPI package is in.
But I didn't find that index in the metadata files ("repositories_with_releases.json" seemed the most likely candidate).
Is it available as a flat file but I'm just too blind to see it?
The problem is that it’s pretty huge and would need to be an artefact. I’ll have a think.
Also why no Azure alongside AWS and Google?
This analysis will be re-done with some other data soon.
OpenAI is one of the supported platforms - A list of providers is at https://docs.github.com/en/code-security/secret-scanning/sec...
Anyway, very cool. I am shocked at how many header files are present.
Another idea - how many unique files are there between releases and how many unique files are there total? Take a sha hash of every file, every commit. Calculate how many shas are shared between releases vs novel (ie # files churned per release). Can then also calculate on the global uniqueness over time. Of course, this means calculating billions of sha sums, so it could take forever, unless you had some cute trick to rip the value out of the git repos directly. Maybe you could even beat the odds and find that 1 in a quadrillion hash collision.
https://play.clickhouse.com/play?user=play#U0VMRUNUIHByb2plY...
Example: https://play.clickhouse.com/play?user=play#U0VMRUNUIHByb2plY...
This is a nice dataset for exploration, although small (only one billion records). Going to upload all lines of code...
I was looking into some browser duckdb WASM setup that reads the parquet files via http but I ran out of steam.
Thanks so much for that!
> Not all files can be committed to GitHub ... very long lines ... VCS directories
Wait so github will reject a push if one of the commits contains a file with very long lines in it?
The “very long lines” exclusion is for text files that are very large but contain less than 5 or so lines. If I remember correctly there are some “py-armour” files that are basically just big dumps of base64 encoded python byte code on two or so lines.
These are likely unique files and so won’t compress well, which bloats the size of the repositories. If you’re interested you can use the SQL console on the datasets page to take a look at the specific files.
And github will block a push containing a commit which creates one of these files?
And git itself does not?
Github has a max size limit per repository. You can push a 150gb git repository to github: it won't stop you, but you'll get a message from support telling you remove it within 48 hours.
By "heuristically excluding some text files that won’t compress well based on their content and size before committing", we are able to keep the size bound of the repositories within those set by Github whilst keeping the majority of useful code.
We have excluded 26,610 .py files for being too large, whilst keeping 414,228,665 .py files. The average size for an excluded .py file is 15 MiB, vs ~10KiB for included files.
1. https://play.clickhouse.com/play?user=play#c2VsZWN0IHNraXBfc...
>There are too many ways to do the same thing, (...)
Fair, but that's a funny statement to make because Python from the start tried to have just one obvious solution for every problem. Maybe that's just what happens with languages over time.
>not type safe
Nitpick: Python is dynamically typed, but is actually quite type safe as used in practice (i.e. type errors are usually caught in runtime instead of silently doing the wrong thing). YMMV of course.
>and I personally don't know many real python pros, the majority are just using python to play with.
The beautiful thing about Python is that you don't have to be a pro to use it effectively :). And I think this may be a result of your professional bubble - for example I don't know any Java pros, but I have no doubts there are many.
You could maybe parse the files and run a similarity function of some kind on class and method bodies, ignoring identifier names.
[1]: Rice's theorem https://en.wikipedia.org/wiki/Rice%27s_theorem
Like why not assign a character to each keyword: 'if' = 'i', 'while' = 'w', 'true' = 't', etc. Then reduce code to this, removing all whitespace comments and identifiers. so `if True: while True: pass` would become `itwtp`.
then the similarity is just an edit distance between two given strings?
This is one of the funniest things I've read all week.
Incredibly there seems to be no sign yet of an S-curve type saturation (which would be only normal at this point of the Python hype cycle).
Would be interesting to control by repeating the analysis with other languages to see if that exponential growth is Python specific or really the exponential growth of all open source
Maybe publish in JOSS?